<script setup lang="ts">
import { NButton, NModal } from 'naive-ui'
import { computed } from 'vue'

import { useIsMobile } from '@/composables/useIsMobile'

const props = defineProps<{
  show: boolean
  title: string
  submitting?: boolean
  submitText?: string
  submitDisabled?: boolean
  danger?: boolean
  width?: number
}>()

const emit = defineEmits<{ 'update:show': [boolean]; submit: [] }>()

const isMobile = useIsMobile()

/** 移动端全屏(100dvh 覆盖底栏与手势区),桌面维持定宽居中 */
const modalStyle = computed(() =>
  isMobile.value
    ? { width: '100vw', height: '100dvh', maxWidth: '100vw', margin: '0', borderRadius: '0' }
    : { width: `${props.width ?? 480}px`, maxWidth: 'calc(100vw - 24px)' },
)
</script>

<template>
  <NModal
    :show="show"
    preset="card"
    :title="title"
    :style="modalStyle"
    :class="isMobile ? 'form-modal-mobile' : ''"
    :mask-closable="!submitting"
    :close-on-esc="!submitting"
    @update:show="emit('update:show', $event)"
  >
    <!-- 标题插槽:需要在标题旁放徽章等富内容时覆盖 -->
    <template v-if="$slots.header" #header>
      <slot name="header" />
    </template>
    <div class="form-modal-body">
      <slot />
    </div>
    <template #footer>
      <div class="flex justify-end gap-2.5">
        <NButton
          :size="isMobile ? 'medium' : 'small'"
          :class="isMobile ? 'flex-1' : ''"
          :disabled="submitting"
          @click="emit('update:show', false)"
        >
          取消
        </NButton>
        <NButton
          :size="isMobile ? 'medium' : 'small'"
          :class="isMobile ? 'flex-1' : ''"
          :type="danger ? 'error' : 'primary'"
          :loading="submitting"
          :disabled="submitDisabled"
          @click="emit('submit')"
        >
          {{ submitText ?? '确定' }}
        </NButton>
      </div>
    </template>
  </NModal>
</template>

<style scoped>
/* 长表单不撑破视口:内容区限高滚动,页脚按钮常驻;
   负 margin + 等量 padding 让滚动条贴弹窗边缘(变量继承自 .n-card) */
.form-modal-body {
  overflow-y: auto;
  margin-inline: calc(-1 * var(--n-padding-left, 24px));
  padding-inline: var(--n-padding-left, 24px);
}
/* 限高只在桌面定宽形态生效:移动全屏由全局 .form-modal-mobile 的 flex:1
   接管高度。不能靠全局规则 max-height:none 覆盖——main.css 先于组件
   scoped 样式加载,同特异性下这里会反超,故直接用断点隔离 */
@media (min-width: 768px) {
  .form-modal-body {
    max-height: min(62vh, calc(100vh - 220px));
  }
}
</style>

<!-- 移动端全屏形态 .form-modal-mobile 的规则在 main.css(全局):
     NModal teleport 到 body,scoped 够不到;且该类被各弹窗跨 chunk 复用 -->
