<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)"
                  :model-value="batchForms[b.batch]"
                  :readonly="false"
                  :purchase-id="String(purchaseId)"
                  :project-type="acceptProjectType"
                  :budget="applyInfo?.budget"
                  :batch-num="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, nextTick } from 'vue'
import { useMessage } from '/@/hooks/message'
import {
  saveCommonConfig as apiSaveCommonConfig,
  getCommonConfigWithBatches,
  updateBatch,
  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 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 || ''
})

/** 项目类型 A:货物 B:工程 C:服务，用于批次表单模版下载 */
const acceptProjectType = computed(() => applyInfo.value?.projectType || rowProjectType.value || 'A')

/** 是否允许编辑该期：第 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 = await getCommonConfigWithBatches(currentId)
    // 防止快速切换：若已打开其他申请单，忽略本次结果
    if (String(purchaseId.value) !== currentId) return

    const config = configRes?.data

    if (config?.common) {
      applyInfo.value = config.common
      // 采购人员和资产管理员始终回填
      commonForm.value.purchaserId = config.common.purchaserId || ''
      commonForm.value.purchaserName = config.common.purchaserName || ''
      commonForm.value.assetAdminId = config.common.assetAdminId || ''
      commonForm.value.assetAdminName = config.common.assetAdminName || ''
      
      // 其他字段仅当存在已保存批次时回填
        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 || '',
            transactionAmount: config.common.transactionAmount || null,
          })
        }
    }

    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
        batchSavedFlags.value[b.batch] = hasSaved
        // 优先使用 templateFiles（包含id和fileTitle），否则降级使用 templateFileIds
        let fileIdsStr = ''
        if (d.accept.templateFiles && d.accept.templateFiles.length > 0) {
          // 使用 templateFiles，格式为 {id: string, fileTitle: string}[]
          fileIdsStr = d.accept.templateFiles.map((f: any) => f.id).join(',')
        } else if (d.accept.templateFileIds) {
          // 降级使用 templateFileIds
          const fileIds = d.accept.templateFileIds
          fileIdsStr = Array.isArray(fileIds) ? fileIds.join(',') : (fileIds || '')
        }
        batchForms[b.batch] = {
          acceptType: '2', // 固定为上传模式
          acceptDate: d.accept.acceptDate || '',
          remark: d.accept.remark || '',
          templateFileIds: fileIdsStr,
          // 保存文件信息用于显示
          _templateFiles: d.accept.templateFiles || [],
        }
        // 通知子组件初始化数据
        await nextTick()
        const batchFormRef = batchFormRefMap.value[b.batch]
        if (batchFormRef?.initData) {
          batchFormRef.initData()
        }
      }
    } 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 ?? ''),
      purchaserId: String(form.purchaserId ?? ''),
      purchaserName: String(form.purchaserName ?? ''),
      assetAdminId: String(form.assetAdminId ?? ''),
      assetAdminName: String(form.assetAdminName ?? ''),
      transactionAmount: form.transactionAmount ?? null,
    })
    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 formData = batchFormRef?.getFormData?.() || batchFormRef?.form
  if (!formData) return

  // acceptDate is now optional - removed the validation check

  // templateFileIds: 提取ID数组
  let fileIds: string[] = []
  if (formData.templateFileIds) {
    if (Array.isArray(formData.templateFileIds)) {
      fileIds = formData.templateFileIds.map((item: any) => {
        if (typeof item === 'string') return item
        if (item && item.id) return item.id
        return null
      }).filter(Boolean)
    } else if (typeof formData.templateFileIds === 'string') {
      fileIds = formData.templateFileIds.split(',').map((s: string) => s.trim()).filter(Boolean)
    }
  }

  saving.value = true
  try {
    await updateBatch({
      id: b.id,
      purchaseId: String(purchaseId.value),
      acceptType: '2', // 固定为上传模式
      acceptDate: formData.acceptDate,
      remark: formData.remark,
      templateFileIds: fileIds,
    })
    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: '',
  purchaserId: '',
  purchaserName: '',
  assetAdminId: '',
  assetAdminName: '',
  transactionAmount: null,
}

/** 将弹窗内所有内容恢复为初始空值（替换整个对象以确保引用变化） */
const resetAllToDefault = () => {
  openToken.value++
  commonForm.value = { ...DEFAULT_COMMON_FORM }
  applyInfo.value = null
  mainTab.value = 'common'
  activeTab.value = '1'
  batchFormRefMap.value = {}
  batches.value = []
  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>
