<template>
  <!-- 移动端布局 -->
  <el-drawer v-if="isMobile" v-model="dialogVisible" :title="dialogTitle" direction="rtl" size="100%" :close-on-press-escape="true" :destroy-on-close="true" :append-to-body="true" class="mobile-form-drawer">
    <div class="mobile-form" v-loading="formLoading">
      <el-form ref="formRef" :model="formData" :rules="formRules" :disabled="isDetail" label-position="top">
        <div class="mobile-form__section">
          <div class="mobile-form__section-title">基本信息</div>
          <el-form-item label="凭证编号" prop="voucherNo"><el-input v-model="formData.voucherNo" disabled placeholder="系统自动生成" /></el-form-item>
          <el-form-item v-if="!isDetail" label="制单日期" prop="voucherDate"><el-date-picker v-model="formData.voucherDate" type="date" placeholder="选择制单日期" value-format="YYYY-MM-DD" style="width:100%" /></el-form-item>
          <el-form-item label="系统名" prop="systemName"><el-input v-model="formData.systemName" placeholder="请输入系统名" /></el-form-item>
          <el-form-item label="摘要" prop="summary"><el-input v-model="formData.summary" placeholder="请输入摘要" @input="syncSummaryToItems" /></el-form-item>
          <el-form-item v-if="formType !== 'create'" label="审核状态" prop="status"><dict-tag :type="DICT_TYPE.ERP_AUDIT_STATUS" :value="formData.status" /></el-form-item>
          <el-form-item label="备注" prop="remark"><el-input v-model="formData.remark" type="textarea" :rows="2" placeholder="请输入备注" /></el-form-item>
        </div>
        <div class="mobile-form__section">
          <div class="mobile-form__section-title">凭证明细</div>
          <div v-for="(item, index) in formData.items" :key="index" class="mobile-item-card">
            <div class="mobile-item-card__header">
              <span class="mobile-item-card__index">#{{ index + 1 }}</span>
              <span class="mobile-item-card__name">{{ item.subjectName || '未选择科目' }}</span>
              <el-button v-if="!isDetail" :disabled="isDetail" @click="removeItem(index)" link type="danger" size="small">删除</el-button>
            </div>
            <div class="mobile-item-card__body">
              <el-form-item label="摘要"><el-input v-model="item.summary" placeholder="请输入摘要" :disabled="isDetail" /></el-form-item>
              <el-form-item label="科目名称"><el-tree-select v-model="item.subjectId" :data="subjectTree" :props="{ label: 'name', value: 'id', children: 'children' }" placeholder="请选择科目名称" check-strictly filterable :disabled="isDetail" style="width:100%" @change="(val) => handleSubjectChange(item, val)" /></el-form-item>
              <el-form-item label="借方金额"><el-input-number v-model="item.debitAmount" :precision="2" :min="0" :controls="false" placeholder="借方金额" :disabled="isDetail || (item.creditAmount > 0)" style="width:100%" @change="(val) => handleDebitChange(item, val)" /></el-form-item>
              <el-form-item label="贷方金额"><el-input-number v-model="item.creditAmount" :precision="2" :min="0" :controls="false" placeholder="贷方金额" :disabled="isDetail || (item.debitAmount > 0)" style="width:100%" @change="(val) => handleCreditChange(item, val)" /></el-form-item>
            </div>
          </div>
          <div class="mobile-item-add" v-if="!isDetail"><el-button @click="addItem" round>+ 添加明细</el-button></div>
          <div class="mobile-item-summary">
            <div class="mobile-item-summary__row"><span>借方合计</span><span class="text-red-500">{{ formatAmount(debitTotal) }}</span></div>
            <div class="mobile-item-summary__row"><span>贷方合计</span><span class="text-blue-500">{{ formatAmount(creditTotal) }}</span></div>
          </div>
          <el-alert v-if="!isBalanced && formData.items.length > 0" title="借贷不平衡，请检查金额" type="warning" :closable="false" class="mt-10px" />
        </div>
      </el-form>
    </div>
    <template #footer>
      <div class="mobile-form__footer">
        <el-button @click="dialogVisible = false" style="flex:1">取 消</el-button>
        <el-button v-if="!isDetail" type="primary" :disabled="formLoading" @click="submitForm" style="flex:2">确 定</el-button>
      </div>
    </template>
  </el-drawer>

  <!-- PC端布局 -->
  <Dialog v-else 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 { ref, reactive, computed } from 'vue'
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'
import { useWindowSize } from '@vueuse/core'

defineOptions({ name: 'BookkeepingVoucherForm' })

const { width } = useWindowSize()
const isMobile = computed(() => width.value < 768)

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>
