<template>
  <Dialog v-model="dialogVisible" title="季度分配编辑" width="1280">
    <div class="mb-16px rounded-8px bg-[var(--el-fill-color-light)] px-16px py-12px text-13px leading-22px text-[var(--el-text-color-secondary)]">
      在这里维护合约规划的分配总控信息和季度分配明细。新增年度默认各季度为 0%，没有比例或比例为 0 的季度不会落库。
    </div>

    <el-form
      ref="formRef"
      v-loading="loading"
      :model="formData"
      :rules="formRules"
      label-width="130px"
    >
      <el-row :gutter="16">
        <el-col :span="8">
          <el-form-item label="总分配(%)" prop="totalDistributionAmount">
            <el-input-number
              v-model="totalDistributionAmountPercent"
              :min="0"
              :precision="2"
              :step="0.01"
              class="!w-1/1"
              controls-position="right"
            />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="已分配">
            <el-input :model-value="formatPercentText(formData.allocatedAmount)" disabled />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="待分配">
            <el-input :model-value="formatPercentText(formData.pendingAmount)" disabled />
          </el-form-item>
        </el-col>
      </el-row>

      <el-row :gutter="16">
        <el-col :span="24">
          <el-form-item label="提取进度备注" prop="progressRemark">
            <el-input
              v-model="formData.progressRemark"
              :rows="3"
              maxlength="500"
              placeholder="请输入这条合约规划整体的季度分配说明"
              show-word-limit
              type="textarea"
            />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>

    <div class="mb-16px flex items-center justify-between">
      <div class="text-14px font-600">季度分配明细</div>
      <el-button plain @click="addDistributionYear">
        <Icon class="mr-5px" icon="ep:plus" />
        新增年度
      </el-button>
    </div>

    <el-table v-loading="loading" :data="quarterRows" border>
      <el-table-column align="center" label="分配年度" width="150">
        <template #default="scope">
          <el-date-picker
            :model-value="toYearPickerValue(scope.row.distributionYear)"
            class="!w-1/1"
            placeholder="请选择年度"
            type="year"
            value-format="YYYY"
            @update:model-value="(value) => updateDistributionYear(scope.row, value)"
          />
        </template>
      </el-table-column>
      <el-table-column align="center" label="操作" width="90" fixed="right">
        <template #default="scope">
          <el-button link type="danger" @click="removeDistributionYear(scope.row)">删除</el-button>
        </template>
      </el-table-column>
      <el-table-column
        v-for="quarter in QUARTER_OPTIONS"
        :key="quarter.value"
        :label="quarter.label"
        min-width="180"
      >
        <template #default="scope">
          <div class="flex flex-col gap-8px">
            <el-input-number
              :model-value="toQuarterPercent(scope.row, quarter.value)"
              :min="0"
              :precision="2"
              :step="0.01"
              class="!w-1/1"
              controls-position="right"
              placeholder="比例(%)"
              @update:model-value="(value) => updateQuarterRatio(scope.row, quarter.value, value)"
            />
          </div>
        </template>
      </el-table-column>
    </el-table>

    <template #footer>
      <el-button :disabled="loading" type="primary" @click="submitForm">保存</el-button>
      <el-button @click="dialogVisible = false">取消</el-button>
    </template>
  </Dialog>
</template>

<script lang="ts" setup>
import type { FormRules } from 'element-plus'
import * as PlanningApi from '@/api/tjt/planning'
import * as PlanningQuarterApi from '@/api/tjt/planningQuarter'
import {
  QUARTER_OPTIONS,
  formatPercentText,
  fromPercentValue,
  toPercentValue
} from '@/views/tjt/shared/planning'

defineOptions({ name: 'TjtQuarterDistributionForm' })

interface QuarterYearRow {
  distributionYear: number
  quarters: PlanningQuarterApi.ProjectPlanningQuarterVO[]
}

const message = useMessage()

const dialogVisible = ref(false)
const loading = ref(false)
const formRef = ref()
const planningId = ref<number>()
const deletedQuarterIds = ref<number[]>([])
const formData = ref<PlanningApi.ProjectPlanningVO>({
  projectId: 0,
  ownershipType: '',
  calculationMethod: '',
  planningContent: '',
  totalDistributionAmount: 1,
  progressRemark: ''
})
const quarterRows = ref<QuarterYearRow[]>([])

const totalDistributionAmountPercent = computed({
  get: () => toPercentValue(formData.value.totalDistributionAmount),
  set: (value) => {
    formData.value.totalDistributionAmount = fromPercentValue(value)
  }
})

const formRules = reactive<FormRules>({
  totalDistributionAmount: [{ required: true, message: '总分配不能为空', trigger: 'blur' }],
  progressRemark: [{ max: 500, message: '提取进度备注长度不能超过 500 个字符', trigger: 'blur' }]
})

const buildQuarterCell = (
  currentPlanningId: number,
  distributionYear: number,
  quarterNo: number
): PlanningQuarterApi.ProjectPlanningQuarterVO => ({
  planningId: currentPlanningId,
  distributionYear,
  quarterNo,
  distributionRatio: undefined,
  distributionAmount: undefined
})

const buildQuarterRows = (
  planning: PlanningApi.ProjectPlanningVO,
  quarters: PlanningQuarterApi.ProjectPlanningQuarterVO[]
) => {
  const yearSet = new Set<number>()
  if (planning.planningStartYear) {
    yearSet.add(planning.planningStartYear)
  }
  quarters.forEach((item) => {
    const distributionYear = Number(item.distributionYear)
    if (!Number.isNaN(distributionYear)) {
      yearSet.add(distributionYear)
    }
  })
  if (yearSet.size === 0) {
    yearSet.add(new Date().getFullYear())
  }
  return Array.from(yearSet)
    .sort((a, b) => a - b)
    .map((distributionYear) => ({
      distributionYear,
      quarters: QUARTER_OPTIONS.map((option) => {
        const quarterNo = Number(option.value)
        const match = quarters.find(
          (item) =>
            Number(item.distributionYear) === distributionYear &&
            Number(item.quarterNo) === quarterNo
        )
        return match
          ? { ...match }
          : buildQuarterCell(planning.id!, distributionYear, quarterNo)
      })
    }))
}

const open = async (id: number) => {
  planningId.value = id
  dialogVisible.value = true
  loading.value = true
  deletedQuarterIds.value = []
  try {
    const planning = await PlanningApi.getProjectPlanning(id)
    formData.value = {
      ...planning,
      totalDistributionAmount: planning.totalDistributionAmount ?? 1,
      progressRemark: planning.progressRemark ?? ''
    }
    const quarterList = await PlanningQuarterApi.getProjectPlanningQuarterListByPlanningId(id)
    quarterRows.value = buildQuarterRows(formData.value, quarterList)
  } finally {
    loading.value = false
  }
}

defineExpose({ open })

const emit = defineEmits(['success'])

const addDistributionYear = () => {
  if (!planningId.value) {
    return
  }
  const maxYear = quarterRows.value.length
    ? Math.max(...quarterRows.value.map((item) => item.distributionYear))
    : formData.value.planningStartYear || new Date().getFullYear()
  const distributionYear = maxYear + 1
  quarterRows.value.push({
    distributionYear,
    quarters: QUARTER_OPTIONS.map((item) =>
      buildQuarterCell(planningId.value!, distributionYear, item.value)
    )
  })
}

const removeDistributionYear = (row: QuarterYearRow) => {
  const removableIds = row.quarters
    .map((item) => item.id)
    .filter((id): id is number => typeof id === 'number')
  if (removableIds.length) {
    deletedQuarterIds.value.push(...removableIds)
  }
  quarterRows.value = quarterRows.value.filter((item) => item !== row)
}

const toYearPickerValue = (value?: number) => (value ? String(value) : undefined)

const updateDistributionYear = (row: QuarterYearRow, value?: string) => {
  row.distributionYear = value ? Number(value) : new Date().getFullYear()
  row.quarters.forEach((quarter) => {
    quarter.distributionYear = row.distributionYear
  })
}

const getQuarterCell = (row: QuarterYearRow, quarterNo: number) => {
  return row.quarters.find((item) => Number(item.quarterNo) === Number(quarterNo))
}

const toQuarterPercent = (row: QuarterYearRow, quarterNo: number) => {
  return toPercentValue(getQuarterCell(row, quarterNo)?.distributionRatio)
}

const updateQuarterRatio = (row: QuarterYearRow, quarterNo: number, value?: number) => {
  const quarter = getQuarterCell(row, quarterNo)
  if (!quarter) {
    return
  }
  quarter.distributionRatio = fromPercentValue(value)
  quarter.distributionAmount = undefined
}

const isZeroQuarter = (quarter: PlanningQuarterApi.ProjectPlanningQuarterVO) => {
  return Number(quarter.distributionRatio || 0) === 0
}

const buildQuarterSavePayload = (
  row: QuarterYearRow,
  quarter: PlanningQuarterApi.ProjectPlanningQuarterVO
): PlanningQuarterApi.ProjectPlanningQuarterSaveVO => ({
  id: quarter.id,
  planningId: planningId.value!,
  distributionYear: row.distributionYear,
  quarterNo: quarter.quarterNo,
  distributionRatio: quarter.distributionRatio
})

const submitForm = async () => {
  if (!formRef.value || !planningId.value) {
    return
  }
  const valid = await formRef.value.validate()
  if (!valid) {
    return
  }
  const yearList = quarterRows.value.map((item) => item.distributionYear)
  if (yearList.some((item) => !item)) {
    message.warning('分配年度不能为空')
    return
  }
  if (new Set(yearList).size !== yearList.length) {
    message.warning('分配年度不能重复')
    return
  }

  loading.value = true
  try {
    await PlanningApi.updateProjectPlanning({
      id: formData.value.id,
      projectId: formData.value.projectId,
      ownershipType: formData.value.ownershipType,
      calculationMethod: formData.value.calculationMethod,
      planningContent: formData.value.planningContent,
      planningAmount: formData.value.planningAmount,
      managementFeeRate: formData.value.managementFeeRate,
      implementationTeam: formData.value.implementationTeam,
      planningStartYear: formData.value.planningStartYear,
      planningArea: formData.value.planningArea,
      designStage: formData.value.designStage,
      currentDesignStageRatio: formData.value.currentDesignStageRatio,
      reviewOutsourceFlag: formData.value.reviewOutsourceFlag,
      reviewOutsourceRatio: formData.value.reviewOutsourceRatio,
      totalDistributionAmount: formData.value.totalDistributionAmount,
      progressRemark: formData.value.progressRemark,
      buildingOrUnitCount: formData.value.buildingOrUnitCount,
      drawingSetFactor: formData.value.drawingSetFactor,
      scaleFactor: formData.value.scaleFactor,
      modificationFactor: formData.value.modificationFactor,
      complexityFactor: formData.value.complexityFactor,
      internalGuidanceUnitPrice: formData.value.internalGuidanceUnitPrice,
      virtualCalculationMethod: formData.value.virtualCalculationMethod,
      workingDayCount: formData.value.workingDayCount,
      workingDayUnitPrice: formData.value.workingDayUnitPrice,
      guidanceUnitPrice: formData.value.guidanceUnitPrice,
      guidanceTotalPrice: formData.value.guidanceTotalPrice,
      calculationRatio: formData.value.calculationRatio
    })

    if (deletedQuarterIds.value.length) {
      await PlanningQuarterApi.deleteProjectPlanningQuarterList(Array.from(new Set(deletedQuarterIds.value)))
      deletedQuarterIds.value = []
    }

    for (const row of quarterRows.value) {
      for (const quarter of row.quarters) {
        const payload = buildQuarterSavePayload(row, quarter)
        if (payload.id) {
          await PlanningQuarterApi.updateProjectPlanningQuarter(payload)
        } else if (!isZeroQuarter(quarter)) {
          await PlanningQuarterApi.createProjectPlanningQuarter(payload)
        }
      }
    }

    message.success('季度分配保存成功')
    dialogVisible.value = false
    emit('success')
  } finally {
    loading.value = false
  }
}
</script>
