<template>
    <hc-new-dialog v-model="isShow" :title="`${dataId ? '编辑' : '新增'}材料调差单`" is-footer-center is-table widths="80rem" @close="modalClose">
        <div class="hc-info-table-form">
            <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
                <hc-info-table>
                    <tr>
                        <hc-info-table-td is-title width="10%">
                            <span>计量期：</span>
                            <i class="i-iconoir-asterisk asterisk-icon" />
                        </hc-info-table-td>
                        <hc-info-table-td>
                            <el-form-item prop="key1">
                                <el-select v-model="formModel.meterPeriodId" placeholder="选择计量期" filterable block>
                                    <el-option v-for="item in measurement" :key="item.id" :label="item.periodName" :value="item.id" />
                                </el-select>
                            </el-form-item>
                        </hc-info-table-td>
                        <hc-info-table-td is-title width="10%">
                            <span>调差期：</span>
                            <i class="i-iconoir-asterisk asterisk-icon" />
                        </hc-info-table-td>
                        <hc-info-table-td>
                            <el-form-item prop="contractPeriodId">
                                <el-select v-model="formModel.contractPeriodId" placeholder="选择调差期" filterable block @change="adjustmentChange">
                                    <template v-for="item in adjustment" :key="item.id">
                                        <el-option v-if="item.approveStatus === 2" :label="item.periodNumber" :value="item.id" />
                                    </template>
                                </el-select>
                            </el-form-item>
                        </hc-info-table-td>
                    </tr>
                    <tr>
                        <hc-info-table-td is-title width="10%">
                            <span>材料名称：</span>
                            <i class="i-iconoir-asterisk asterisk-icon" />
                        </hc-info-table-td>
                        <hc-info-table-td>
                            <el-form-item prop="contractMaterialId">
                                <el-select v-model="formModel.contractMaterialId" placeholder="选择材料名称" filterable block :disabled="isNullES(formModel.meterPeriodId)" @change="materialNameChange">
                                    <el-option v-for="item in materialName" :key="item.id" :label="item.materialName" :value="item.id" />
                                </el-select>
                            </el-form-item>
                        </hc-info-table-td>
                        <hc-info-table-td is-title width="10%">
                            <span>施工期市场价格：</span>
                            <i class="i-iconoir-asterisk asterisk-icon" />
                        </hc-info-table-td>
                        <hc-info-table-td>
                            <el-form-item prop="currentPrice">
                                <el-input v-model="formModel.currentPrice" disabled>
                                    <template #suffix>元</template>
                                    <template #append>
                                        <el-button type="primary" class="hc-input-btn" color="#C99AD7" @click="realTimePriceClick">
                                            <hc-icon name="add" />
                                            <span>选择实时价格</span>
                                        </el-button>
                                    </template>
                                </el-input>
                            </el-form-item>
                        </hc-info-table-td>
                    </tr>
                    <tr>
                        <hc-info-table-td is-title width="10%">调差月份：</hc-info-table-td>
                        <hc-info-table-td>
                            <el-form-item>
                                <el-date-picker v-if="isAdjustDate" v-model="formModel.adjustMonth" class="block" type="month" format="YYYY-MM" value-format="YYYY-MM" :disabled="isNullES(formModel.currentPriceId)" :disabled-date="disabledDate" />
                            </el-form-item>
                        </hc-info-table-td>
                        <hc-info-table-td is-title width="10%">材料基准价格：</hc-info-table-td>
                        <hc-info-table-td>
                            <el-form-item>
                                <el-input v-model="formModel.materialPrice" disabled>
                                    <template #suffix>元</template>
                                </el-input>
                            </el-form-item>
                        </hc-info-table-td>
                    </tr>
                    <tr>
                        <hc-info-table-td is-title width="10%">
                            <span>材料数量：</span>
                            <i class="i-iconoir-asterisk asterisk-icon" />
                        </hc-info-table-td>
                        <hc-info-table-td>
                            <el-form-item prop="materialTotal">
                                <el-input v-model="formModel.materialTotal" />
                            </el-form-item>
                        </hc-info-table-td>
                        <hc-info-table-td is-title width="10%">价差幅度：</hc-info-table-td>
                        <hc-info-table-td>
                            <el-form-item>
                                <el-input v-model="formModel.rangePriceRatio" disabled>
                                    <template #suffix>%</template>
                                </el-input>
                            </el-form-item>
                        </hc-info-table-td>
                    </tr>
                    <tr>
                        <hc-info-table-td is-title width="10%">调差金额：</hc-info-table-td>
                        <hc-info-table-td width="auto" colspan="3">
                            <el-form-item>
                                <el-input v-model="formModel.adjustMoney" disabled />
                            </el-form-item>
                        </hc-info-table-td>
                    </tr>
                    <tr>
                        <hc-info-table-td is-title width="10%">材料调差计算式：</hc-info-table-td>
                        <hc-info-table-td width="auto" colspan="3">
                            <el-form-item>
                                <el-input v-model="formModel.adjustCalculation" type="textarea" :rows="4" resize="none" disabled />
                            </el-form-item>
                        </hc-info-table-td>
                    </tr>
                </hc-info-table>
            </el-form>
        </div>
        <div class="hc-info-form-table">
            <el-divider border-style="dashed">
                <el-segmented v-model="tab_key" :options="['材料明细', '上传附件']" />
            </el-divider>
            <div v-if="tab_key === '材料明细'" class="loop-refresh-icon" @click="getMaterialDetail">
                <hc-icon name="loop-left" />
            </div>
            <div v-if="tab_key === '材料明细'" class="table-body">
                <hc-table :column="tableColumn1" :datas="tableData1" :index-style="{ width: 60 }" :loading="tableLoading1">
                    <template #changeTotal="{ row }">
                        <el-input v-model="row.changeTotal" @blur="changeTotalBlur(row)" />
                    </template>
                </hc-table>
            </div>
            <div v-if="tab_key === '上传附件'" class="table-body">
                <div class="table-upload-attachment">
                    <el-button @click="uploadAttachmentClick">点击上传附件</el-button>
                </div>
                <div class="table-upload">
                    <hc-table :column="tableColumn2" :datas="tableData2" :index-style="{ width: 60 }" :loading="tableLoading2">
                        <template #action="{ row, index }">
                            <el-link type="primary" @click="previewFile(row)">预览</el-link>
                            <el-link type="danger" @click="delFile(index)">删除</el-link>
                        </template>
                    </hc-table>
                </div>
            </div>
        </div>
        <template #footer>
            <el-button hc-btn @click="modalClose">取消</el-button>
            <el-button :loading="saveLoaing" hc-btn type="primary" @click="modalSave">保存</el-button>
        </template>
    </hc-new-dialog>
    <!-- 材料实时发布价格 -->
    <hc-new-dialog v-model="isRealTimePrice" ui="hc-realTime-price" title="材料实时发布价格" is-table :footer="false" widths="70rem" @close="realTimePriceClose">
        <div class="h-full">
            <div class="search-year-month mb-14px">
                <div class="w-48">
                    <el-date-picker v-model="yearMonth" class="block" type="month" format="YYYY-MM" value-format="YYYY-MM" placeholder="调差月份" clearable @change="getMaterialCurrentPrice" />
                </div>
            </div>
            <div class="realTime-price-table">
                <hc-table :column="tableColumn3" :datas="tableData3" :index-style="{ width: 60 }" :loading="tableLoading3">
                    <template #action="{ row }">
                        <el-link v-if="formModel.currentPriceId === row.id" type="danger" @click="deselectTimePrice">取消选择</el-link>
                        <el-link v-else type="primary" @click="rowRealTimePrice(row)">选择</el-link>
                    </template>
                </hc-table>
            </div>
        </div>
    </hc-new-dialog>
    <!-- 上传附件 -->
    <hc-new-dialog v-model="isAttachment" title="上传文件" is-footer-center widths="30rem" @close="attachmentClose">
        <hc-form-upload v-model="formUploadFile" is-res :options="{ type: 'list', props: uploadFormProps, isArr: true, num: 0 }" @success="fileUploadSuccess" />
        <template #footer>
            <el-button hc-btn @click="attachmentClose">取消</el-button>
            <el-button hc-btn type="primary" @click="attachmentSave">确认</el-button>
        </template>
    </hc-new-dialog>
</template>

<script setup>
import dayjs from 'dayjs'
import { nextTick, ref, watch } from 'vue'
import { useAppStore } from '~src/store'
import { isNumberReg } from '~uti/tools'
import mainApi from '~api/debit-pay/material/material'
import { deepClone, formValidate, getArrValue, getObjValue, isNullES, newWindow } from 'js-fast-way'

const props = defineProps({
    ids: {
        type: [String, Number],
        default: '',
    },
})

//事件
const emit = defineEmits(['finish', 'close'])

//初始变量
const useAppState = useAppStore()
const contractId = ref(useAppState.getContractId)
const projectId = ref(useAppState.getProjectId)

//双向绑定
// eslint-disable-next-line no-undef
const isShow = defineModel('modelValue', {
    default: false,
})

//监听
const dataId = ref(props.ids)
watch(() => props.ids, (id) => {
    dataId.value = id
}, { deep: true })

//监听
watch(isShow, (val) => {
    if (val) detailsModalShow()
})

//分段器
const tab_key = ref('材料明细')

//表单数据
const formRef = ref(null)
const formModel = ref({})
const formRules = {
    meterPeriodId: {
        required: true,
        trigger: 'blur',
        message: '请选择计量期',
    },
    contractPeriodId: {
        required: true,
        trigger: 'blur',
        message: '请选择调差期',
    },
    contractMaterialId: {
        required: true,
        trigger: 'blur',
        message: '请选择材料名称',
    },
    currentPrice: {
        required: true,
        trigger: 'blur',
        message: '请选择实时价格',
    },
    materialTotal: {
        required: true,
        trigger: 'blur',
        message: '请填写材料数量',
    },
}

//处理数据
const detailsModalShow = () => {
    getPeriodMeasurement()
    getPeriodAdjustment()
    getMaterialName()
    //过去数据详情
    if (!isNullES(dataId.value)) {
        getDetailData()
    } else {
        isAdjustDate.value = true
    }
}

//获取数据详情
const getDetailData = async () => {
    const { code, data, msg } = await mainApi.detail(dataId.value)
    if (code === 200) {
        const obj = getObjValue(data)
        formModel.value = obj
        tableData1.value = obj.details
        tableData2.value = obj.files
        try {
            adjustStartDate.value = dayjs(obj.startDate).format('YYYY-MM') ?? ''
            adjustEndDate.value = dayjs(obj.endDate).format('YYYY-MM') ?? ''
        } catch { /* empty */ }
        isAdjustDate.value = true
    } else {
        window.$message.error(msg ?? '数据异常')
        modalClose()
    }
}

//获取计量期
const measurement = ref([])
const getPeriodMeasurement = async () => {
    const { data } = await mainApi.periodMeasurement(contractId.value)
    measurement.value = getArrValue(data)
}

//获取调差期
const adjustment = ref([])
const getPeriodAdjustment = async () => {
    const { data } = await mainApi.periodAdjustment(contractId.value)
    adjustment.value = getArrValue(data)
}

//获取调差期号
const adjustmentChange = () => {
    const { contractPeriodId } = formModel.value
    const info = adjustment.value.find((item) => item.id === contractPeriodId)
    formModel.value.contractPeriodNumber = info.periodNumber ?? ''
}

//获取材料名称
const materialName = ref([])
const getMaterialName = async () => {
    const { meterPeriodId } = formModel.value
    const { data } = await mainApi.materialName(contractId.value, meterPeriodId)
    materialName.value = getArrValue(data)
}
const materialNameChange = () => {
    const { contractMaterialId } = formModel.value
    const info = materialName.value.find((item) => item.id === contractMaterialId)
    isAdjusts.value = 0
    formModel.value.currentPriceId = null
    formModel.value.currentPrice = ''
    formModel.value.adjustMonth = null
    formModel.value.materialPrice = info.price ?? ''
    formModel.value.materialName = info.materialName ?? ''
    formModel.value.rangePriceRatio = ''
    formModel.value.adjustCalculation = ''
    formModel.value.materialValidityId = null
    tableData1.value = []
    tableLoading1.value = false
}

//禁用时间
const isAdjustDate = ref(false)
const disabledDate = (time) => {
    if (isNullES(adjustStartDate.value) || isNullES(adjustEndDate.value)) {
        return true
    }
    //处理时间
    const date = dayjs(time).format('YYYY-MM') //当前时间
    const isStart = dayjs(date).isSame(dayjs(adjustStartDate.value)) //是否等于开始时间
    const isEnd = dayjs(date).isSame(dayjs(adjustEndDate.value)) //是否等于结束时间
    const isBefore = dayjs(date).isBefore(dayjs(adjustEndDate.value)) //是否在结束时间之前
    const isAfter = dayjs(date).isAfter(dayjs(adjustStartDate.value)) //是否在开始时间之后
    //如果当前时间，大于等于开始时间，小于等于结束时间，则可用，否则禁用
    if ((isStart || isAfter) && (isEnd || isBefore)) {
        return false
    } else {
        return true
    }
}

//材料实时发布价格表格
const yearMonth = ref(null)
const tableColumn3 = [
    { key: 'nodeName', name: '有效时间' },
    { key: 'materialNumber', name: '材料编号', width: 100, align: 'center' },
    { key: 'materialName', name: '材料名称' },
    { key: 'unit', name: '材料单位', width: 100, align: 'center' },
    { key: 'currentPrice', name: '单价（元）', width: 100, align: 'center' },
    { key: 'action', name: '操作', width: 100, align: 'center' },
]
const tableData3 = ref([])
const tableLoading3 = ref(false)
const getMaterialCurrentPrice = async () => {
    const { contractMaterialId } = formModel.value
    //发起请求
    tableLoading3.value = true
    const { data } = await mainApi.getMaterialCurrentPrice({
        yearMonth: yearMonth.value,
        materialId: contractMaterialId,
        contractId: contractId.value,
    })
    tableData3.value = getArrValue(data)
    tableLoading3.value = false
}

//材料实时发布价格
const isRealTimePrice = ref(false)
const realTimePriceClick = () => {
    const { contractMaterialId } = formModel.value
    if (isNullES(contractMaterialId)) {
        window.$message.warning('请先选择材料名称')
        return
    }
    isRealTimePrice.value = true
    getMaterialCurrentPrice()
}

//选择实时发布价格
const adjustStartDate = ref('')
const adjustEndDate = ref('')
const isAdjusts = ref(1) //0不允许，1允许
const rowRealTimePrice = async (row) => {
    const { id, currentPrice, startDate, endDate, materialValidityId } = row
    const { code, msg, data } = await mainApi.getMaterialRangePrice({
        priceId: id,
    })
    const { isAdjust, rangePriceRatio, adjustCalculation } = getObjValue(data)
    if (code !== 200) {
        window.$message.error(msg ?? '操作失败')
        return
    }
    isAdjustDate.value = false
    let startDate1 = '', endDate1 = ''
    try {
        startDate1 = dayjs(startDate).format('YYYY-MM') ?? ''
        endDate1 = dayjs(endDate).format('YYYY-MM') ?? ''
    } catch { /* empty */ }
    isAdjusts.value = isAdjust ?? 0
    formModel.value.startDate = startDate1
    formModel.value.endDate = endDate1
    formModel.value.currentPriceId = id
    formModel.value.currentPrice = currentPrice
    formModel.value.adjustMonth = startDate1
    formModel.value.rangePriceRatio = rangePriceRatio
    formModel.value.adjustCalculation = adjustCalculation
    formModel.value.materialValidityId = materialValidityId
    adjustStartDate.value = startDate1
    adjustEndDate.value = endDate1
    await nextTick(() => {
        isAdjustDate.value = true
        realTimePriceClose()
    })
}

//关闭材料实时发布价格
const realTimePriceClose = () => {
    isRealTimePrice.value = false
    tableData3.value = []
    tableLoading3.value = false
}

//材料明细表格
const tableColumn1 = [
    { key: 'meterNumber', name: '计量单编号' },
    { key: 'formNumber', name: '清单编号' },
    { key: 'formName', name: '清单名称' },
    { key: 'unit', name: '单位', width: 120, align: 'center' },
    { key: 'meterTotal', name: '计量数量', width: 120, align: 'center' },
    { key: 'changeTotal', name: '可调量', width: 120, align: 'center' },
    { key: 'adjustFactor', name: '调差系数', width: 120, align: 'center' },
    { key: 'adjustTotal', name: '调差数量', width: 120, align: 'center' },
]
const tableData1 = ref([])
const tableLoading1 = ref(false)
const getMaterialDetail = async () => {
    const {
        contractPeriodId, contractMaterialId, currentPrice,
        materialValidityId, materialPrice, rangePriceRatio,
    } = formModel.value
    if (isNullES(contractPeriodId)) {
        window.$message.warning('请先选择调差期')
    } else if (isNullES(contractMaterialId)) {
        window.$message.warning('请先选择材料名称')
    } else if (isNullES(currentPrice) || isNullES(materialValidityId)) {
        window.$message.warning('请先选择实时价格')
    } else if (isNullES(materialPrice)) {
        window.$message.warning('请先选择材料基准价格不为空的')
    } else if (isNullES(rangePriceRatio)) {
        window.$message.warning('请先选择价差幅度不为空的')
    } else {
        //获取数据
        const { code, msg, data } = await mainApi.getMaterialDetail({
            contractMaterialId: contractMaterialId,
            contractPeriodId: contractPeriodId,
            projectId: projectId.value,
            contractId: contractId.value,
            currentPrice: currentPrice,
            materialPrice: materialPrice,
            materialValidityId: materialValidityId,
            rangePriceRatio: rangePriceRatio,
        })
        tableData1.value = getArrValue(data)
        if (code !== 200 && msg) {
            window.$message.error(msg)
        }
    }
}

//价格取消选择
const deselectTimePrice = () => {
    isAdjustDate.value = false
    const form = deepClone(formModel.value)
    tableData1.value = []
    formModel.value = {
        id: form.id,
        meterPeriodId: form.meterPeriodId,
        materialPrice: form.materialPrice,
        materialName: form.materialName,
        contractPeriodId: form.contractPeriodId,
        contractMaterialId: form.contractMaterialId,
        contractPeriodNumber: form.contractPeriodNumber,
        materialTotal: form.materialTotal,
    }
    isAdjustDate.value = true
    realTimePriceClose()
}

//可调量失去焦点
const changeTotalBlur = (row) => {
    const { meterTotal, changeTotal } = row
    if (!isNumberReg(changeTotal)) {
        row.changeTotal = meterTotal
        window.$message.warning('请输入正确的可调量')
    } else if (changeTotal > meterTotal) {
        row.changeTotal = meterTotal
        window.$message.warning('只能小于等于计量数量')
    }
}

//上传附件
const tableColumn2 = [
    { key: 'fileName', name: '文件名称' },
    { key: 'fileSizeName', name: '文件大小', align: 'center' },
    { key: 'fileUpTime', name: '更新时间', align: 'center' },
    { key: 'fileSuffix', name: '文件类型', align: 'center' },
    { key: 'action', name: '操作', width: 120, align: 'center' },
]
const tableData2 = ref([])
const tableLoading2 = ref(false)

//附件上传
const formUploadFile = ref([])
const uploadFormProps = {
    url: 'link',
    name: 'originalName',
}

//点击上传附件
const isAttachment = ref(false)
const uploadAttachmentClick = () => {
    isAttachment.value = true
}

//附件上传成功的回调
const fileUploadSuccess = ({ res }, resolve) => {
    resolve(res)
}

//提交确定
const attachmentSave = async () => {
    const list = formUploadFile.value
    for (let i = 0; i < list.length; i++) {
        tableData2.value.push({
            fileName: list[i].originalName,
            filePdfUrl: list[i].pdfUrl,
            fileSizeName: list[i].fileSizeName,
            fileSuffix: list[i].fileSuffix,
            fileType: list[i].fileType,
            fileUpTime: list[i].fileDate,
            fileUrl: list[i].link,
        })
    }
    attachmentClose()
}

//关闭上传附件
const attachmentClose = () => {
    isAttachment.value = false
    formUploadFile.value = []
}

//预览附件
const previewFile = ({ fileUrl }) => {
    if (isNullES(fileUrl)) {
        window.$message.warning('此文件已不存在，请删除后，重新上传')
        return
    }
    newWindow(fileUrl)
}

//预览附件
const delFile = (index) => {
    tableData2.value.splice(index, 1)
}

//保存
const saveLoaing = ref(false)
const modalSave = async () => {
    const isForm = await formValidate(formRef.value)
    if (!isForm) return
    //处理表单
    const form = formModel.value
    form.details = tableData1.value
    form.files = tableData2.value
    form.projectId = projectId.value
    form.contractId = contractId.value
    //发起请求
    let res = {}
    if (isNullES(form.id)) {//新增
        res = await mainApi.add(form)
    } else {
        res = await mainApi.update(form)
    }
    //处理结果
    const { code, msg } = res
    if (code === 200) {
        window.$message.success('保存成功')
        modalClose()
        emit('finish')
    } else {
        window.$message.error(msg ?? '保存失败')
    }
}

//关闭弹窗
const modalClose = () => {
    isShow.value = false
    emit('close')
    dataId.value = ''
    formModel.value = {}
    isAdjustDate.value = false
    tableData1.value = []
    tableLoading1.value = false
    tableData2.value = []
    tableLoading2.value = false
    tableData3.value = []
    tableLoading3.value = false
}
</script>

<style lang="scss">
.hc-info-table-form {
    position: relative;
    height: 357px;
    .el-form .hc-info-table-td .el-form-item {
        margin-bottom: 0;
        .el-form-item__error {
            display: none;
        }
    }
    .asterisk-icon {
        position: absolute;
        display: inline-block;
        color: red;
        font-size: 8px;
    }
    .el-input-group__append .hc-input-btn {
        background-color: var(--el-button-bg-color);
        border-radius: 0 3px 3px 0;
        font-weight: 400;
        color: #000000;
    }
}
.hc-info-form-table {
    position: relative;
    height: calc(100% - 382px);
    .el-divider {
        border-color: #008200;
    }
    .el-divider .el-divider__text {
        padding: 0 4px;
    }
    .el-divider .el-segmented {
        --el-segmented-color: #008200;
        --el-segmented-item-hover-color: #008200;
        --el-segmented-item-selected-bg-color: #008200;
        --el-segmented-item-hover-bg-color: transparent;
        border: 1px solid #008200;
    }
    .loop-refresh-icon {
        position: absolute;
        color: #008200;
        font-size: 26px;
        height: 32px;
        width: 32px;
        display: flex;
        align-items: center;
        justify-content: center;
        background: white;
        left: 10px;
        top: -14px;
        cursor: pointer;
        &:hover {
            color: #035903;
        }
    }
    .table-body {
        position: relative;
        height: calc(100% - 25px);
        .table-upload-attachment {
            position: relative;
            margin-bottom: 10px;
            .el-button {
                width: 100%;
            }
        }
        .table-upload {
            position: relative;
            height: calc(100% - 42px);
        }
    }
}
.el-overlay-dialog .el-dialog.hc-new-dialog.hc-modal-table.hc-realTime-price {
    --el-dialog-margin-top: 100px;
    height: calc(100% - 200px);
    .realTime-price-table {
        position: relative;
        height: calc(100% - 46px);
    }
}
</style>
