<template>
  <el-dialog
    v-model="visible"
    title="履约验收"
    width="75%"
    :close-on-click-modal="false"
    destroy-on-close
    class="purchasing-accept-modal"
    @close="handleClose"
  >
    <div v-loading="loading" class="modal-body" :key="String(purchaseId)">
      <div class="main-tabs">
        <div class="main-tab-nav">
          <div
            class="main-tab-item"
            :class="{ active: mainTab === 'common' }"
            @click="mainTab = 'common'"
          >
            公共信息
          </div>
          <div
            class="main-tab-item"
            :class="{ active: mainTab === 'batch' }"
            @click="mainTab = 'batch'"
          >
            {{ commonForm?.isInstallment === '0' ? '验收' : '分期验收' }}{{ commonForm?.isInstallment !== '0' && batches.length > 0 ? ` (${batches.length})` : '' }}
          </div>
        </div>
        <div class="main-tab-content">
          <div v-show="mainTab === 'common'" class="tab-content">
            <AcceptCommonForm
              :key="`${purchaseId}-${openToken}`"
              :reset-key="openToken"
              ref="commonFormRef"
              v-model="commonForm"
              :purchase-id="purchaseId"
              :project-name="applyInfo?.projectName"
              :dept-name="applyInfo?.deptName"
            />
          </div>
          <div v-show="mainTab === 'batch'" class="tab-content">
            <div v-if="batches.length > 0">
              <div v-show="commonForm?.isInstallment !== '0'" class="batch-tabs">
                <div
                  v-for="b in batches"
                  :key="b.id"
                  class="batch-tab-item"
                  :class="{ active: String(b.batch) === activeTab, disabled: !canEditBatch(b.batch) }"
                  @click="canEditBatch(b.batch) && (activeTab = String(b.batch))"
                >
                  <span>第{{ b.batch }}期</span>
                  <el-tag v-if="isBatchCompleted(b)" type="success" size="small">已填</el-tag>
                  <el-tag v-else-if="!canEditBatch(b.batch)" type="info" size="small">需先完成上一期</el-tag>
                </div>
              </div>
              <div class="batch-panel">
                <AcceptBatchForm
                  v-for="b in batches"
                  v-show="String(b.batch) === activeTab"
                  :key="b.id"
                  :ref="(el) => setBatchFormRef(b.batch, el)"
                  v-model="batchForms[b.batch]"
                  :can-fill="canFillForm"
                  :readonly="false"
                  :purchase-id="String(purchaseId)"
                  :acceptance-items="acceptanceItems"
                  :batch-num="b.batch"
                  :previous-batches-teams="getPreviousBatchesTeams(b.batch)"
                />
              </div>
            </div>
            <div v-else class="tip-box">
              <el-alert type="info" :closable="false" show-icon>
                请先在「公共信息」中填写并点击「保存公共配置」，系统将按分期次数自动生成验收批次
              </el-alert>
            </div>
          </div>
        </div>
      </div>
    </div>

    <template #footer>
      <span>
        <el-button @click="handleClose">关 闭</el-button>
        <el-button
          v-if="mainTab === 'common' || batches.length === 0"
          type="primary"
          @click="saveCommonConfig"
          :loading="saving"
        >
          保存公共配置
        </el-button>
        <el-button
          v-else-if="mainTab === 'batch' && activeBatchId"
          type="primary"
          @click="saveCurrentBatch"
          :loading="saving"
        >
          保存第{{ activeTab }}期
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, reactive, computed, watch, nextTick } from 'vue'
import { useMessage } from '/@/hooks/message'
import {
  saveCommonConfig as apiSaveCommonConfig,
  getCommonConfigWithBatches,
  updateBatch,
  canFillForm as apiCanFillForm,
  getAcceptanceItems,
  getDetail,
} from '/@/api/purchase/purchasingAccept'
import AcceptCommonForm from './AcceptCommonForm.vue'
import AcceptBatchForm from './AcceptBatchForm.vue'

const emit = defineEmits(['refresh'])

const visible = ref(false)
const loading = ref(false)
const saving = ref(false)
const purchaseId = ref<string | number>('')
const applyInfo = ref<any>(null)
const rowProjectType = ref<string>('A')
const canFillForm = ref(true)
const acceptanceItems = ref<any[]>([])
const batches = ref<any[]>([])
const mainTab = ref('common')
const activeTab = ref('1')
const commonFormRef = ref()
const batchFormRefMap = ref<Record<number, any>>({})
/** 使用 ref 并在每次打开时替换整个对象，确保子组件能感知引用变化并清空 */
const commonForm = ref<Record<string, any>>({})
/** 每次打开自增，用于强制 AcceptCommonForm 重新挂载，确保公共信息彻底清空 */
const openToken = ref(0)
const batchForms = reactive<Record<number, any>>({})
/** 记录哪些期已保存到服务器，用于控制“下一期可填”：只有上一期已保存才允许填下一期 */
const batchSavedFlags = ref<Record<number, boolean>>({})

const setBatchFormRef = (batch: number, el: any) => {
  if (el) batchFormRefMap.value[batch] = el
}

const activeBatchId = computed(() => {
  const b = batches.value.find((x: any) => String(x.batch) === activeTab.value)
  return b?.id || ''
})

const getPreviousBatchesTeams = (batchNum: number) => {
  const list: { batch: number; team: any[] }[] = []
  for (let n = 1; n < batchNum; n++) {
    const team = batchForms[n]?.acceptTeam
    if (Array.isArray(team) && team.length > 0) {
      list.push({ batch: n, team })
    }
  }
  return list
}

/** 是否允许编辑该期：第 1 期始终可编辑；第 N 期仅当第 1～N-1 期均已保存后才可编辑 */
const canEditBatch = (batch: number) => {
  if (batch === 1) return true
  for (let i = 1; i < batch; i++) {
    if (!batchSavedFlags.value[i]) return false
  }
  return true
}

/** 该期是否已保存（用于 tab 上显示“已填”标签） */
const isBatchCompleted = (b: any) => {
  return !!batchSavedFlags.value[b.batch]
}

const isBatchCompletedByIdx = (batch: number) => {
  return !!batchSavedFlags.value[batch]
}

const loadData = async () => {
  if (!purchaseId.value) return
  const currentId = String(purchaseId.value)
  loading.value = true
  try {
    const [configRes, canFillRes] = await Promise.all([
      getCommonConfigWithBatches(currentId),
      apiCanFillForm(currentId),
    ])
    // 防止快速切换：若已打开其他申请单，忽略本次结果
    if (String(purchaseId.value) !== currentId) return

    const config = configRes?.data
    canFillForm.value = !!canFillRes?.data

    if (config?.common) {
      applyInfo.value = config.common
      // 仅当存在已保存批次时，才用接口数据回填公共信息；否则保持 open() 中的默认清空值
      if (config?.batches?.length) {
        Object.assign(commonForm.value, {
          hasContract: config.common.hasContract || '0',
          contractId: config.common.contractId || '',
          isInstallment: config.common.isInstallment || '0',
          totalPhases: config.common.totalPhases || 1,
          supplierName: config.common.supplierName || '',
          supplierContact: config.common.supplierContact || '',
          purchaserId: config.common.purchaserId || '',
          purchaserName: config.common.purchaserName || '',
          assetAdminId: config.common.assetAdminId || '',
          assetAdminName: config.common.assetAdminName || '',
        })
      }
    }

    const projectType = applyInfo.value?.projectType || rowProjectType.value || 'A'
    const typeMap: Record<string, string> = { A: 'A', B: 'B', C: 'C' }
    const at = typeMap[projectType] || 'A'
    const itemsRes = await getAcceptanceItems(at)
    if (String(purchaseId.value) !== currentId) return
    acceptanceItems.value = itemsRes?.data || []

    if (config?.batches?.length) {
      batches.value = config.batches.sort((a: any, b: any) => (a.batch || 0) - (b.batch || 0))
      activeTab.value = String(batches.value[0]?.batch || '1')
      mainTab.value = 'batch'
      for (const b of batches.value) {
        if (!batchForms[b.batch]) batchForms[b.batch] = {}
      }
      await loadBatchDetails()
      if (String(purchaseId.value) !== currentId) return
    } else {
      batches.value = []
    }
  } catch (e: any) {
    useMessage().error(e?.msg || '加载失败')
  } finally {
    loading.value = false
  }
}

const loadBatchDetails = async () => {
  for (const b of batches.value) {
    batchSavedFlags.value[b.batch] = false
  }
  for (const b of batches.value) {
    try {
      const res = await getDetail(String(purchaseId.value), b.batch)
      const d = res?.data
      if (d?.accept) {
        // 仅当该期在服务端有验收日期（且验收方式）时才视为已保存，避免空结构被当成“已填”
        const hasSaved = !!(d.accept.acceptDate && d.accept.acceptType)
        batchSavedFlags.value[b.batch] = hasSaved
        const itemMap = (acceptanceItems.value || []).reduce((acc: any, it: any) => {
          acc[it.id] = it
          return acc
        }, {})
        batchForms[b.batch] = {
          acceptType: d.accept.acceptType || '1',
          acceptDate: d.accept.acceptDate || '',
          remark: d.accept.remark || '',
          templateFileIds: d.accept.templateFileIds || [],
          acceptContents: (d.contents || []).map((c: any) => {
            const cfg = itemMap[c.configId]
            return {
              configId: c.configId,
              itemName: cfg?.itemName || '',
              type: cfg?.type,
              isQualified: c.isQualified || '1',
              remark: c.remark || '',
            }
          }),
          acceptTeam: (d.team || []).map((t: any) => ({
            name: t.name,
            deptCode: t.deptCode,
            deptName: t.deptName,
          })),
        }
        if (batchForms[b.batch].acceptTeam.length < 3) {
          while (batchForms[b.batch].acceptTeam.length < 3) {
            batchForms[b.batch].acceptTeam.push({ name: '', deptCode: '', deptName: '' })
          }
        }
        if (acceptanceItems.value.length && (!batchForms[b.batch].acceptContents || batchForms[b.batch].acceptContents.length === 0)) {
          batchForms[b.batch].acceptContents = acceptanceItems.value.map((it: any) => ({
            configId: it.id,
            itemName: it.itemName,
            type: it.type,
            isQualified: '1',
            remark: '',
          }))
        }
      }
    } catch (_) {}
  }
}

const saveCommonConfig = async () => {
  const formRef = commonFormRef.value
  const valid = await formRef?.validate?.().catch(() => false)
  if (!valid) return
  // 直接从子组件 form 读取，确保拿到用户填写的最新值（避免 v-model 同步延迟）
  const form = formRef?.form || commonForm.value
  const isInstallment = form.isInstallment === '1' || form.isInstallment === 1
  if (isInstallment && (!form.totalPhases || form.totalPhases < 1)) {
    useMessage().error('请填写分期次数')
    return
  }
  saving.value = true
  try {
    await apiSaveCommonConfig({
      purchaseId: String(purchaseId.value),
      hasContract: form.hasContract ?? '0',
      contractId: form.contractId ?? '',
      isInstallment: form.isInstallment ?? '0',
      totalPhases: isInstallment ? (Number(form.totalPhases) || 1) : 1,
      supplierName: String(form.supplierName ?? ''),
      supplierContact: String(form.supplierContact ?? ''),
      purchaserId: String(form.purchaserId ?? ''),
      purchaserName: String(form.purchaserName ?? ''),
      assetAdminId: String(form.assetAdminId ?? ''),
      assetAdminName: String(form.assetAdminName ?? ''),
    })
    useMessage().success('保存成功')
    await loadData()
  } catch (e: any) {
    useMessage().error(e?.msg || '保存失败')
  } finally {
    saving.value = false
  }
}

const saveCurrentBatch = async () => {
  const curBatch = Number(activeTab.value)
  const batchFormRef = batchFormRefMap.value[curBatch]
  const valid = await batchFormRef?.validate?.().catch(() => false)
  if (!valid) return

  const b = batches.value.find((x: any) => String(x.batch) === activeTab.value)
  if (!b?.id) return
  const form = batchForms[curBatch]
  if (!form) return

  if (!form.acceptType) {
    useMessage().error('请选择验收方式')
    return
  }
  if (!form.acceptDate) {
    useMessage().error('请选择验收日期')
    return
  }

  const team = (form.acceptTeam || []).filter((m: any) => m?.name)
  if (team.length < 3 || team.length % 2 === 0) {
    useMessage().error('验收小组至少3人且为单数')
    return
  }

  saving.value = true
  try {
    await updateBatch({
      id: b.id,
      purchaseId: String(purchaseId.value),
      acceptType: form.acceptType,
      acceptDate: form.acceptDate,
      remark: form.remark,
      templateFileIds: form.templateFileIds || [],
      acceptContents: form.acceptContents || [],
      acceptTeam: team,
    })
    useMessage().success('保存成功')
    batchSavedFlags.value[curBatch] = true
    await loadData()
  } catch (e: any) {
    useMessage().error(e?.msg || '保存失败')
  } finally {
    saving.value = false
  }
}

const handleClose = () => {
  visible.value = false
  emit('refresh')
}

const DEFAULT_COMMON_FORM = {
  hasContract: '0',
  contractId: '',
  isInstallment: '0',
  totalPhases: 1,
  supplierName: '',
  supplierContact: '',
  purchaserId: '',
  purchaserName: '',
  assetAdminId: '',
  assetAdminName: '',
}

/** 将弹窗内所有内容恢复为初始空值（替换整个对象以确保引用变化） */
const resetAllToDefault = () => {
  openToken.value++
  commonForm.value = { ...DEFAULT_COMMON_FORM }
  applyInfo.value = null
  mainTab.value = 'common'
  activeTab.value = '1'
  batchFormRefMap.value = {}
  batches.value = []
  acceptanceItems.value = []
  canFillForm.value = true
  Object.keys(batchForms).forEach((k) => delete batchForms[Number(k)])
  batchSavedFlags.value = {}
}

const open = async (row: any) => {
  purchaseId.value = row?.id ?? ''
  rowProjectType.value = row?.projectType || 'A'

  // 1. 先将弹窗内所有内容恢复为初始空值
  resetAllToDefault()

  // 2. 显示弹窗并开启 loading，避免接口返回前展示旧数据
  visible.value = true
  loading.value = true

  // 3. 等待 Vue 完成渲染，确保子组件已接收并展示空值
  await nextTick()
  await nextTick()

  // 4. 再进行接口查询并覆盖
  await loadData()
}

defineExpose({ open })
</script>

<style scoped>
.modal-body {
  padding: 0;
  max-height: 70vh;
  overflow-y: auto;
  overflow-x: hidden;
}
.main-tab-nav {
  display: flex;
  gap: 4px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--el-border-color);
}
.main-tab-item {
  padding: 12px 20px;
  cursor: pointer;
  color: var(--el-text-color-regular);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: all 0.2s;
}
.main-tab-item:hover {
  color: var(--el-color-primary);
}
.main-tab-item.active {
  color: var(--el-color-primary);
  font-weight: 600;
  border-bottom-color: var(--el-color-primary);
}
.main-tab-content {
  padding-top: 4px;
}
.tab-content {
  min-height: 200px;
  display: block;
}
.tip-box {
  padding: 20px 0;
}
.batch-tabs {
  display: flex;
  gap: 8px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}
.batch-tab-item {
  padding: 8px 16px;
  border: 1px solid var(--el-border-color);
  border-radius: 4px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  transition: all 0.2s;
}
.batch-tab-item:hover:not(.disabled) {
  border-color: var(--el-color-primary);
  color: var(--el-color-primary);
}
.batch-tab-item.active {
  background: var(--el-color-primary);
  border-color: var(--el-color-primary);
  color: #fff;
}
.batch-tab-item.disabled {
  cursor: not-allowed;
  opacity: 0.6;
}
.batch-panel {
  min-height: 200px;
}
</style>

<style>
/* 弹窗横向滚动修复，需非 scoped 以影响 el-dialog */
.purchasing-accept-modal .el-dialog__body {
  overflow-x: hidden;
}
</style>
