<template>
  <Dialog v-model="dialogVisible" :title="dialogTitle" width="900px">
    <el-form
      ref="formRef"
      v-loading="formLoading"
      :model="formData"
      :rules="formRules"
      :disabled="isDetail"
      label-width="100px"
    >
      <el-row :gutter="20">
        <el-col :span="8">
          <el-form-item label="凭证编号" prop="voucherNo">
            <el-input v-model="formData.voucherNo" disabled placeholder="系统自动生成" />
          </el-form-item>
        </el-col>
        <el-col :span="8" v-if="!isDetail">
          <el-form-item label="制单日期" prop="voucherDate">
            <el-date-picker
              v-model="formData.voucherDate"
              type="date"
              placeholder="选择制单日期"
              value-format="YYYY-MM-DD"
              class="!w-full"
            />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="系统名" prop="systemName">
            <el-input v-model="formData.systemName" placeholder="请输入系统名" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="16">
          <el-form-item label="摘要" prop="summary">
            <el-input v-model="formData.summary" placeholder="请输入摘要" @input="syncSummaryToItems" />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="审核状态" prop="status" v-if="formType !== 'create'">
            <dict-tag :type="DICT_TYPE.ERP_AUDIT_STATUS" :value="formData.status" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="24">
          <el-form-item label="备注" prop="remark">
            <el-input v-model="formData.remark" type="textarea" :rows="2" placeholder="请输入备注" />
          </el-form-item>
        </el-col>
      </el-row>

      <!-- 凭证明细 -->
      <el-divider content-position="left">凭证明细</el-divider>
      <el-table :data="formData.items" border style="width: 100%">
        <el-table-column label="序号" type="index" width="60" align="center" />
        <el-table-column label="摘要" min-width="150">
          <template #default="{ row }">
            <el-input v-model="row.summary" placeholder="请输入摘要" :disabled="isDetail" />
          </template>
        </el-table-column>
        <el-table-column label="科目名称" min-width="200">
          <template #default="{ row }">
            <el-tree-select
              v-model="row.subjectId"
              :data="subjectTree"
              :props="{ label: 'name', value: 'id', children: 'children' }"
              placeholder="请选择科目名称"
              check-strictly
              filterable
              :disabled="isDetail"
              class="!w-full"
              @change="(val) => handleSubjectChange(row, val)"
            />
          </template>
        </el-table-column>
        <el-table-column label="借方金额" width="140">
          <template #default="{ row }">
            <el-input-number
              v-model="row.debitAmount"
              :precision="2"
              :min="0"
              :controls="false"
              placeholder="借方金额"
              :disabled="isDetail || (row.creditAmount > 0)"
              class="!w-full"
              @change="(val) => handleDebitChange(row, val)"
            />
          </template>
        </el-table-column>
        <el-table-column label="贷方金额" width="140">
          <template #default="{ row }">
            <el-input-number
              v-model="row.creditAmount"
              :precision="2"
              :min="0"
              :controls="false"
              placeholder="贷方金额"
              :disabled="isDetail || (row.debitAmount > 0)"
              class="!w-full"
              @change="(val) => handleCreditChange(row, val)"
            />
          </template>
        </el-table-column>
        <el-table-column label="操作" width="80" align="center" v-if="!isDetail">
          <template #default="{ $index }">
            <el-button link type="danger" @click="removeItem($index)">
              <Icon icon="ep:delete" />
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 添加明细按钮和合计 -->
      <el-row :gutter="20" class="mt-10px">
        <el-col :span="12">
          <el-button v-if="!isDetail" type="primary" plain @click="addItem">
            <Icon icon="ep:plus" class="mr-5px" />
            添加明细
          </el-button>
        </el-col>
        <el-col :span="12" class="text-right">
          <span class="mr-20px">借方合计: <strong class="text-red-500">{{ formatAmount(debitTotal) }}</strong></span>
          <span>贷方合计: <strong class="text-blue-500">{{ formatAmount(creditTotal) }}</strong></span>
        </el-col>
      </el-row>

      <!-- 借贷平衡提示 -->
      <el-alert
        v-if="!isBalanced && formData.items.length > 0"
        title="借贷不平衡，请检查金额"
        type="warning"
        :closable="false"
        class="mt-10px"
      />
    </el-form>

    <template #footer>
      <el-button @click="dialogVisible = false">取 消</el-button>
      <el-button v-if="!isDetail" type="primary" :disabled="formLoading" @click="submitForm">
        确 定
      </el-button>
    </template>
  </Dialog>
</template>

<script lang="ts" setup>
import { DICT_TYPE } from '@/utils/dict'
import { formatDate } from '@/utils/formatTime'
import * as BookkeepingVoucherApi from '@/api/erp/finance/bookkeeping'
import { SubjectApi } from '@/api/erp/finance/subject'

defineOptions({ name: 'BookkeepingVoucherForm' })

const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗

const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中
const formType = ref('') // 表单的类型：create - 新增；update - 修改；detail - 详情
const formData = ref({
  id: undefined,
  voucherNo: '',
  voucherDate: '',
  summary: '',
  systemName: '',
  remark: '',
  status: undefined,
  items: [] as any[]
})
const formRules = reactive({
  voucherDate: [{ required: true, message: '制单日期不能为空', trigger: 'blur' }],
  summary: [{ required: true, message: '摘要不能为空', trigger: 'blur' }]
})
const formRef = ref() // 表单 Ref
const subjectTree = ref<any[]>([]) // 科目名称树

// 计算属性
const isDetail = computed(() => formType.value === 'detail')
const debitTotal = ref(0)
const creditTotal = ref(0)
const isBalanced = computed(() => {
  return Math.abs(debitTotal.value - creditTotal.value) < 0.01
})

/** 格式化金额 */
const formatAmount = (amount: number) => {
  return amount.toFixed(2)
}

/** 计算合计 */
const calculateTotal = () => {
  debitTotal.value = formData.value.items.reduce((sum, item) => {
    return sum + (item.debitAmount || 0)
  }, 0)
  creditTotal.value = formData.value.items.reduce((sum, item) => {
    return sum + (item.creditAmount || 0)
  }, 0)
}

/** 借方金额变更 - 清空贷方金额 */
const handleDebitChange = (row: any, val: number) => {
  if (val && val > 0) {
    row.creditAmount = undefined
  }
  calculateTotal()
}

/** 贷方金额变更 - 清空借方金额 */
const handleCreditChange = (row: any, val: number) => {
  if (val && val > 0) {
    row.debitAmount = undefined
  }
  calculateTotal()
}

/** 添加明细 */
const addItem = () => {
  formData.value.items.push({
    summary: formData.value.summary || '', // 自动使用主表摘要
    subjectId: undefined,
    subjectName: '',
    debitAmount: undefined,
    creditAmount: undefined
  })
}

/** 同步主表摘要到明细表 */
const syncSummaryToItems = (val: string) => {
  // 将主表摘要同步到所有明细行
  formData.value.items.forEach(item => {
    item.summary = val
  })
}

/** 删除明细 */
const removeItem = (index: number) => {
  formData.value.items.splice(index, 1)
  calculateTotal()
}

/** 科目变更 */
const handleSubjectChange = (row: any, val: number) => {
  // 查找科目名称
  const findSubject = (tree: any[], id: number): any => {
    for (const item of tree) {
      if (item.id === id) {
        return item
      }
      if (item.children && item.children.length > 0) {
        const found = findSubject(item.children, id)
        if (found) return found
      }
    }
    return null
  }
  const subject = findSubject(subjectTree.value, val)
  if (subject) {
    row.subjectName = subject.name
  }
}

/** 打开弹窗 */
const open = async (type: string, id?: number) => {
  dialogVisible.value = true
  dialogTitle.value = type === 'create' ? '新增记账凭证' : type === 'update' ? '编辑记账凭证' : '记账凭证详情'
  formType.value = type
  resetForm()

  // 加载科目名称树
  try {
    subjectTree.value = await SubjectApi.getSubjectTree()
  } catch (e) {
    console.error('加载科目名称失败', e)
  }

  // 修改或详情时，加载数据
  if (id) {
    formLoading.value = true
    try {
      const data = await BookkeepingVoucherApi.BookkeepingVoucherApi.getVoucher(id)
      formData.value = data
      if (!formData.value.items) {
        formData.value.items = []
      }
      calculateTotal()
    } finally {
      formLoading.value = false
    }
  } else {
    // 新增时，设置默认制单日期为当天
    formData.value.voucherDate = formatDate(new Date(), 'YYYY-MM-DD')
    // 添加一行空明细
    addItem()
  }
}
defineExpose({ open }) // 提供 open 方法，用于打开弹窗

/** 提交表单 */
const submitForm = async () => {
  // 校验表单
  await formRef.value.validate()

  // 校验明细
  if (formData.value.items.length === 0) {
    message.warning('请至少添加一条凭证明细')
    return
  }

  // 校验每条明细
  for (let i = 0; i < formData.value.items.length; i++) {
    const item = formData.value.items[i]
    if (!item.subjectId) {
      message.warning(`第${i + 1}行明细请选择科目名称`)
      return
    }
    if (!item.debitAmount && !item.creditAmount) {
      message.warning(`第${i + 1}行明细请填写借方或贷方金额`)
      return
    }
  }

  // 校验借贷平衡
  if (!isBalanced.value) {
    message.warning('借贷不平衡，请检查金额')
    return
  }

  // 提交请求
  formLoading.value = true
  try {
    const data = { ...formData.value }
    if (formType.value === 'create') {
      await BookkeepingVoucherApi.BookkeepingVoucherApi.createVoucher(data)
      message.success(t('common.createSuccess'))
    } else {
      await BookkeepingVoucherApi.BookkeepingVoucherApi.updateVoucher(data)
      message.success(t('common.updateSuccess'))
    }
    dialogVisible.value = false
    // 发送操作成功的事件
    emit('success')
  } finally {
    formLoading.value = false
  }
}

/** 重置表单 */
const resetForm = () => {
  formData.value = {
    id: undefined,
    voucherNo: '',
    voucherDate: '',
    summary: '',
    systemName: '',
    remark: '',
    status: undefined,
    items: []
  }
  debitTotal.value = 0
  creditTotal.value = 0
  formRef.value?.resetFields()
}

const emit = defineEmits(['success']) // 定义 success 事件
</script>
