<script setup lang="ts">
import AForm from '@/components/AForm/index.vue'
import { FormConfigType } from '@/components/AForm/type'
import { ToolbarConfigType } from '@/components/AToolbar/type'
import { ColumnConfigType } from '@/components/ATable/type'
import { StrAnyObj, StrAnyObjArr } from '@/typings'
import { useHandleData } from '@/utils/useHandleData'
import {
  addApi,
  deleteApi,
  editApi,
  excelExportApi,
  getDetailApi,
  getPageApi,
  retrieveApi
} from '@/api/business/payment/requests'
import { getPageApi as getCorporationPageApi } from '@/api/business/corporation/corporation'
import DeptTreeSelect from '@/views/components/DeptTreeSelect/index.vue'
import { getPageApi as getCapitalAccountPageApi } from '@/api/business/capital/account'
import { getDictByCode } from '@/utils/dict'
import MoneyPDF from '@/components/PDF/moneyPDF.vue'
import { getPdf } from '@/utils/getPdf.js'

const queryRef = ref<InstanceType<typeof AForm>>()
const formRef = ref<InstanceType<typeof AForm>>()

const showQuery = ref<boolean>(true)
const selectKeys = ref<string[]>([])
const pageTotal = ref<number>(0)

const queryData = ref<StrAnyObj>({ pageNum: 1, pageSize: 10 })
const tableData = ref<StrAnyObjArr>([])
const formData = ref<StrAnyObj>({ paymentRequestsDetailList: [{}] })

const dialogTitle = ref<string>('')
const dialogVisible = ref<boolean>(false)

const dialogPrint = ref<boolean>(false)
const rowData = ref<StrAnyObj>({})

const deptIdRef = ref<InstanceType<typeof DeptTreeSelect>>()
const selectDeptIdRef = ref<InstanceType<typeof DeptTreeSelect>>()

const disabled = ref(false)

const queryConfig: FormConfigType[] = [
  {
    type: 'select',
    prop: 'corporationId',
    label: '归属公司',
    keyName: 'id',
    labelName: 'name',
    async option() {
      const data = await getCorporationPageApi({ searchAll: true })
      return data.records
    }
  },
  {
    type: 'slot',
    prop: 'deptId',
    label: '归属部门'
  },
  {
    type: 'select',
    prop: 'type',
    label: '请款类型',
    dict: 'payment_requests_type'
  },
  {
    type: 'select',
    prop: 'payType',
    label: '付款方式',
    dict: 'pay_type'
  },
  {
    type: 'select',
    prop: 'approvalStatus',
    label: '审批状态',
    option: [
      {
        key: 0,
        label: '待提交'
      },
      {
        key: 1,
        label: '审批中'
      },
      {
        key: 2,
        label: '审批通过'
      },
      {
        key: 4,
        label: '终止'
      },
      {
        key: 6,
        label: '撤销'
      },
      {
        key: 7,
        label: '取回'
      }
    ]
  },
  {
    type: 'select',
    prop: 'paymentStatus',
    label: '放款状态',
    option: [
      {
        key: 0,
        label: '未打款'
      },
      {
        key: 1,
        label: '部分打款'
      },
      {
        key: 2,
        label: '已打款'
      }
    ]
  }
]

const toolbarConfig: ToolbarConfigType[] = [
  {
    common: 'search',
    click() {
      queryData.value.pageNum = 1
      getPage()
    }
  },
  {
    common: 'reset',
    click() {
      queryRef.value?.resetFields()
      getPage()
    }
  },
  {
    common: 'add',
    click() {
      disabled.value = false
      dialogVisible.value = true
      dialogTitle.value = '新增'
      nextTick(() => deptIdRef.value?.load())
    }
  },
  {
    text: '导出',
    icon: 'Download',
    type: 'primary',
    click() {
      excelExportApi(queryData.value).then(() => {
        ElMessage.success('导出成功')
      })
    }
  }
]

const columnConfig: ColumnConfigType[] = [
  {
    prop: 'corporationName',
    label: '归属公司'
  },
  {
    prop: 'deptName',
    label: '归属部门'
  },
  {
    prop: 'type',
    label: '请款类型',
    dict: 'payment_requests_type'
  },
  {
    prop: 'userName',
    label: '请款人'
  },
  {
    prop: 'createTime',
    label: '请款时间'
  },
  {
    prop: 'useTime',
    label: '用款时间'
  },
  {
    prop: 'useRemark',
    label: '用款说明',
    showOverflowTooltip: true
  },
  {
    prop: 'totalAmount',
    label: '请款金额'
  },
  {
    prop: 'payType',
    label: '付款方式',
    dict: 'pay_type'
  },
  {
    prop: 'capitalAccountName',
    label: '付款账户'
  },
  {
    prop: 'approvalStatus',
    label: '审批状态',
    formatter(row) {
      switch (row.approvalStatus) {
        case 0:
          return '待提交'
        case 1:
          return '审批中'
        case 2:
          return '审批通过'
        case 4:
          return '驳回'
        case 6:
          return '撤销'
        case 7:
          return '取回'
        default:
          return ''
      }
    }
  },
  {
    prop: 'paymentStatus',
    label: '放款状态',
    formatter(row) {
      switch (row.paymentStatus) {
        case 0:
          return '未打款'
        case 1:
          return '部分打款'
        case 2:
          return '已打款'
        default:
          return ''
      }
    }
  },
  {
    width: 250,
    handleConfig: [
      {
        text: '取回',
        if(row){
          return row.approvalStatus == 1
        },
        click(row) {
          retrieveApi({ businessId: row.id }).then(() => {
            ElMessage.success('取回成功')
            getPage()
          })
        }
      },
      {
        text: '重新发起',
        if(row) {
          return row.approvalStatus == 0 || row.approvalStatus == 7
        },
        click(row) {
          dialogVisible.value = true
          dialogTitle.value = '重新发起'
          disabled.value = false
          getDetailApi({ id: row.id }).then((resp: StrAnyObj) => {
            formData.value = resp
          })
          nextTick(() => deptIdRef.value?.load())
        }
      },
      {
        common: 'detail',
        click(row) {
          dialogVisible.value = true
          dialogTitle.value = '详情'
          disabled.value = true
          nextTick(() => deptIdRef.value?.load())
          getDetailApi({ id: row.id }).then((resp: StrAnyObj) => {
            formData.value = resp
          })
        }
      },
      {
        text: '打印',
        click(row) {
          rowData.value = row
          dialogPrint.value = true
        }
      }
    ]
  }
]

const formConfig: FormConfigType[] = [
  {
    type: 'select',
    prop: 'corporationId',
    label: '归属公司',
    keyName: 'id',
    labelName: 'name',
    async option() {
      const data = await getCorporationPageApi({ searchAll: true })
      return data.records
    },
    rule: [{ required: true, message: '归属公司id不能为空', trigger: 'blur' }]
  },
  {
    type: 'slot',
    prop: 'deptId',
    label: '归属部门',
    rule: [{ required: true, message: '部门id不能为空', trigger: 'blur' }]
  },
  {
    type: 'select',
    prop: 'type',
    label: '请款类型',
    dict: 'payment_requests_type',
    rule: [{ required: true, message: '请款类型不能为空', trigger: 'blur' }]
  },
  {
    type: 'datePicker',
    prop: 'useTime',
    label: '用款时间',
    datePickerType: 'datetime',
    format: 'YYYY-MM-DD HH:mm:ss',
    valueFormat: 'YYYY-MM-DD HH:mm:ss'
  },
  {
    type: 'input',
    itemType: 'textarea',
    prop: 'useRemark',
    label: '用款说明',
    rows: 3,
    span: 24,
    placeholder: '自动拼接请款明细中的款项说明',
    disabled: true
  },
  {
    type: 'upload',
    prop: 'atts',
    label: '上传附件',
    span: 24
  },
  {
    type: 'slot',
    prop: 'detailTable',
    label: '请款明细',
    span: 24
  },
  {
    type: 'input',
    prop: 'totalAmount',
    label: '付款总金额',
    disabled: true,
    placeholder: '自动统计请款明细中的请款金额'
  },
  {
    type: 'inputNumber',
    prop: 'documentQuantity',
    label: '单据数量',
    min: 0,
    precision: 0,
    rule: [{ required: true, message: '单据数量不能为空', trigger: 'blur' }]
  },
  {
    type: 'select',
    prop: 'payType',
    label: '付款方式',
    dict: 'pay_type',
    rule: [{ required: true, message: '付款方式不能为空', trigger: 'blur' }]
  },
  {
    type: 'select',
    prop: 'capitalAccountId',
    label: '付款账户',
    keyName: 'id',
    labelName: 'accountAlias',
    async option() {
      const data = await getCapitalAccountPageApi({ searchAll: true })
      return data.records
    }
  },
  {
    type: 'input',
    prop: 'accountName',
    label: '户名'
  },
  {
    type: 'input',
    prop: 'account',
    label: '银行账号'
  },
  {
    type: 'input',
    prop: 'depositBank',
    label: '开户银行'
  },
  {
    type: 'input',
    prop: 'correspondentNumber',
    label: '联行号/SWIFT Code'
  }
]

const detailTableColumnConfig: ColumnConfigType[] = [
  {
    slot: 'expenseType',
    label: '费用类型',
    width: 250
  },
  {
    slot: 'remark',
    label: '款项说明'
  },
  {
    slot: 'amount',
    label: '请款金额',
    width: 180
  },
  {
    width: 100,
    if: () => !disabled.value,
    handleConfig: [
      {
        common: 'delete',
        click(row, index) {
          formData.value.paymentRequestsDetailList.splice(index, 1)
          updateAmount()
        }
      }
    ]
  }
]

onMounted(() => {
  getPage()
  selectDeptIdRef.value?.load()
})

function getPage() {
  getPageApi(queryData.value).then((resp) => {
    tableData.value = resp.records
    pageTotal.value = resp.total
  })
}

function tableSelectionChange(item: StrAnyObjArr) {
  selectKeys.value = item.map((item) => item.id)
}

function formSubmit() {
  formRef.value?.validate(() => {
    if (formData.value.paymentRequestsDetailList.length === 0) {
      ElMessage.error('请款明细为空，无法提交')
      return
    }

    for (const item of formData.value.paymentRequestsDetailList) {
      if (!item.expenseType) {
        ElMessage.error('请款明细存在费用类型为空，无法提交')
        return
      }
      if (!item.remark) {
        ElMessage.error('请款明细存在款项说明为空，无法提交')
        return
      }
      if (!item.amount) {
        ElMessage.error('请款明细存在请款金额为空，无法提交')
        return
      }
    }

    if (formData.value.id) {
      editApi(formData.value).then(() => {
        dialogVisible.value = false
        ElMessage.success('修改成功')
        getPage()
      })
    } else {
      addApi(formData.value).then(() => {
        dialogVisible.value = false
        ElMessage.success('新增成功')
        getPage()
      })
    }
  })
}

function formClosed() {
  formRef.value?.resetFields()
}

function handleRemove(idList: string[]) {
  useHandleData('是否确认删除？', () => {
    deleteApi({ idList }).then(() => {
      ElMessage.success('删除成功')
      getPage()
    })
  })
}

function addPaymentRequestsDetailList() {
  formData.value.paymentRequestsDetailList.push({})
}

async function updateDetailRemark() {
  const expenseTypes = await getDictByCode('expense_type')
  const expenseMap = new Map<number, string>()
  for (const item of expenseTypes) {
    expenseMap.set(item.value, item.label)
  }
  formData.value.useRemark = formData.value.paymentRequestsDetailList
    .map(
      (item) =>
        `【${expenseMap.get(item.expenseType) ?? ''}】 - ${item.remark ?? ''} - ${item.amount ?? ''}`
    )
    .join('\n')
}

function updateAmount() {
  formData.value.totalAmount = formData.value.paymentRequestsDetailList
    .map((item) => item.amount)
    .filter((item) => item !== '' && item !== null && item !== undefined)
    .reduce((pre, next) => pre + next, 0)

  updateDetailRemark()
}
const printObj = ref({
  id: 'pdfDom',
  popTitle: '',
  extraCss:
    'https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.css, https://cdn.bootcdn.net/ajax/libs/hover.css/2.3.1/css/hover-min.css',
  extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>'
})
const clickDownload = () => {
  getPdf('请款PDF文件')
}
</script>

<template>
  <div>
    <el-card v-if="showQuery">
      <a-form ref="queryRef" v-model="queryData" :config="queryConfig" :span="6">
        <template #deptId>
          <dept-tree-select ref="selectDeptIdRef" v-model="formData.deptId" />
        </template>
      </a-form>
    </el-card>

    <a-table
      :data="tableData"
      :page-total="pageTotal"
      :toolbar-config="toolbarConfig"
      :column-config="columnConfig"
      v-model:showQuery="showQuery"
      v-model:page-num="queryData.pageNum"
      v-model:page-size="queryData.pageSize"
      @page-num-change="getPage"
      @page-size-change="getPage"
      @selection-change="tableSelectionChange"
    >
    </a-table>

    <a-dialog
      v-model="dialogVisible"
      :title="dialogTitle"
      :footer="!disabled"
      @submit="formSubmit"
      @closed="formClosed"
      width="1400px"
      height="200px"
    >
      <a-form ref="formRef" v-model="formData" :config="formConfig" :span="12" :disabled="disabled">
        <template #deptId>
          <dept-tree-select ref="deptIdRef" v-model="formData.deptId" :disabled="disabled" />
        </template>
        <template #detailTable>
          <a-table
            :data="formData.paymentRequestsDetailList"
            :columnConfig="detailTableColumnConfig"
            style="width: 100%"
            :card="false"
          >
            <template #expenseType="scope">
              <a-select
                v-model="scope.row.expenseType"
                dict="expense_type"
                :disabled="disabled"
                @change="updateDetailRemark"
              />
            </template>
            <template #remark="scope">
              <a-input
                v-model="scope.row.remark"
                type="textarea"
                :rows="2"
                @change="updateDetailRemark"
                :disabled="disabled"
              />
            </template>
            <template #amount="scope">
              <a-inputNumber
                v-model="scope.row.amount"
                :min="0.01"
                :precision="2"
                @change="updateAmount"
                :disabled="disabled"
              />
            </template>
          </a-table>
          <el-button
            v-if="!disabled"
            style="width: 100%; margin-bottom: 20px"
            type="primary"
            @click="addPaymentRequestsDetailList"
          >
            添加行
          </el-button>
        </template>
      </a-form>
    </a-dialog>

    <a-dialog :footer="false" v-if="dialogPrint" v-model="dialogPrint" title="打印" width="840px">
      <MoneyPDF :rowData="rowData"></MoneyPDF>
      <template #footer>
        <div>
          <el-button @click="dialogPrint = false" size="large">取消</el-button>
          <el-button type="primary" v-print="printObj" size="large">打印</el-button>
          <el-button type="primary" @click="clickDownload()" size="large">下载PDF</el-button>
        </div>
      </template>
    </a-dialog>
  </div>
</template>
