<template>
  <Dialog v-model="dialogVisible" :title="dialogTitle" width="1120">
    <el-form
      ref="formRef"
      v-loading="formLoading"
      :model="formData"
      :rules="formRules"
      label-width="150px"
    >
      <el-divider content-position="left">规划信息</el-divider>
      <el-row :gutter="16">
        <el-col :span="8">
          <el-form-item label="归属类型">
            <el-input :model-value="ownershipTypeLabel" disabled />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="产值计算方式" prop="calculationMethod">
            <el-select
              v-model="formData.calculationMethod"
              class="!w-1/1"
              placeholder="请选择产值计算方式"
            >
              <el-option
                v-for="item in calculationMethodOptions"
                :key="String(item.value)"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="规划内容">
            <el-input :model-value="formData.planningContent" disabled />
          </el-form-item>
        </el-col>
      </el-row>

      <el-row :gutter="16">
        <el-col :span="8">
          <el-form-item label="规划金额(元)">
            <el-input :model-value="formatAmountText(formData.planningAmount)" disabled />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="管理费率(%)">
            <el-input :model-value="formatPercentText(formData.managementFeeRate)" disabled />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="实施团队">
            <el-input :model-value="formData.implementationTeam || '-'" disabled />
          </el-form-item>
        </el-col>
      </el-row>

      <el-row :gutter="16">
        <el-col :span="8">
          <el-form-item label="设计部位" prop="designPart">
            <el-select
              v-model="formData.designPart"
              class="!w-1/1"
              clearable
              placeholder="请选择设计部位"
            >
              <el-option
                v-for="item in DESIGN_PART_OPTIONS"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="建筑类型" prop="buildingType">
            <el-input
              v-model="formData.buildingType"
              maxlength="100"
              placeholder="请输入建筑类型"
            />
          </el-form-item>
        </el-col>
      </el-row>

      <el-divider content-position="left">测算参数</el-divider>
      <el-row :gutter="16">
        <el-col :span="8">
          <el-form-item label="开始年度" prop="planningStartYear">
            <el-date-picker
              v-model="planningStartYearValue"
              class="!w-1/1"
              placeholder="请选择开始年度"
              type="year"
              value-format="YYYY"
            />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="工程总面积(m²)" prop="planningArea">
            <el-input-number
              v-model="formData.planningArea"
              :min="0"
              :precision="2"
              :step="100"
              class="!w-1/1"
              controls-position="right"
            />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="合同单价(元/m²)">
            <el-input :model-value="contractUnitPricePreview" disabled />
          </el-form-item>
        </el-col>
      </el-row>

      <el-row :gutter="16">
        <el-col :span="8">
          <el-form-item label="设计阶段" prop="designStage">
            <el-select
              v-model="formData.designStage"
              class="!w-1/1"
              placeholder="请选择设计阶段"
            >
              <el-option
                v-for="item in designStageOptions"
                :key="String(item.value)"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>

      <el-row :gutter="16">
        <el-col :span="8">
          <el-form-item label="本次设计阶段比例(%)" prop="currentDesignStageRatio">
            <el-input-number
              v-model="currentDesignStageRatioPercent"
              :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="审核审定是否外包" prop="reviewOutsourceFlag">
            <el-switch
              v-model="formData.reviewOutsourceFlag"
              active-text="是"
              inactive-text="否"
              @change="handleReviewOutsourceFlagChange"
            />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="审核审定占比(%)" prop="reviewOutsourceRatio">
            <el-input-number
              v-model="reviewOutsourceRatioPercent"
              :min="0"
              :precision="2"
              :step="0.01"
              class="!w-1/1"
              controls-position="right"
            />
          </el-form-item>
        </el-col>
      </el-row>

      <el-row :gutter="16">
        <el-col v-if="showCalculationRatioField" :span="8">
          <el-form-item :label="`${calculationRatioLabel}(%)`" prop="calculationRatio">
            <el-input-number
              v-model="calculationRatioPercent"
              :min="0"
              :precision="2"
              :step="0.01"
              class="!w-1/1"
              controls-position="right"
            />
          </el-form-item>
        </el-col>
        <el-col :span="showCalculationRatioField ? 8 : 12">
          <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-row>

      <template v-if="showMajorFactorFields">
        <el-divider content-position="left">专业所测算参数</el-divider>
        <el-row :gutter="16">
          <el-col :span="8">
            <el-form-item label="楼栋数/户型数" prop="buildingOrUnitCount">
              <el-input-number
                v-model="formData.buildingOrUnitCount"
                :min="0"
                :precision="0"
                :step="1"
                class="!w-1/1"
                controls-position="right"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="套图系数" prop="drawingSetFactor">
              <el-input-number
                v-model="formData.drawingSetFactor"
                :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="规模系数" prop="scaleFactor">
              <el-input-number
                v-model="formData.scaleFactor"
                :min="0"
                :precision="2"
                :step="0.01"
                class="!w-1/1"
                controls-position="right"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="16">
          <el-col :span="8">
            <el-form-item label="修改系数" prop="modificationFactor">
              <el-input-number
                v-model="formData.modificationFactor"
                :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="复杂系数/复杂等级(%)" prop="complexityFactor">
              <el-input-number
                v-model="complexityFactorPercent"
                :min="0"
                :precision="2"
                :step="0.01"
                class="!w-1/1"
                controls-position="right"
              />
            </el-form-item>
          </el-col>
        </el-row>
      </template>

      <template v-if="showInternalGuidanceUnitPriceField">
        <el-divider content-position="left">指导价法参数</el-divider>
        <el-row :gutter="16">
          <el-col :span="8">
            <el-form-item label="内部指导单价(元/m²)" prop="internalGuidanceUnitPrice">
              <el-input-number
                v-model="formData.internalGuidanceUnitPrice"
                :min="0"
                :precision="2"
                :step="1"
                class="!w-1/1"
                controls-position="right"
              />
            </el-form-item>
          </el-col>
        </el-row>
      </template>

      <template v-if="showVirtualOutputSection">
        <el-divider content-position="left">虚拟产值法参数</el-divider>
        <el-row :gutter="16">
          <el-col :span="8">
            <el-form-item label="虚拟产值计算方式" prop="virtualCalculationMethod">
              <el-select
                v-model="formData.virtualCalculationMethod"
                class="!w-1/1"
                placeholder="请选择虚拟产值计算方式"
              >
                <el-option
                  v-for="item in virtualCalculationMethodOptions"
                  :key="String(item.value)"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col v-if="showWorkingDayFields" :span="8">
            <el-form-item label="工日" prop="workingDayCount">
              <el-input-number
                v-model="formData.workingDayCount"
                :min="0"
                :precision="2"
                :step="1"
                class="!w-1/1"
                controls-position="right"
              />
            </el-form-item>
          </el-col>
          <el-col v-if="showWorkingDayFields" :span="8">
            <el-form-item label="工日单价(元)" prop="workingDayUnitPrice">
              <el-input-number
                v-model="formData.workingDayUnitPrice"
                :min="0"
                :precision="2"
                :step="100"
                class="!w-1/1"
                controls-position="right"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row v-if="showGuidanceUnitPriceField" :gutter="16">
          <el-col :span="8">
            <el-form-item label="指导单价(元/m²)" prop="guidanceUnitPrice">
              <el-input-number
                v-model="formData.guidanceUnitPrice"
                :min="0"
                :precision="2"
                :step="1"
                class="!w-1/1"
                controls-position="right"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row v-if="showGuidanceTotalPriceField" :gutter="16">
          <el-col :span="8">
            <el-form-item label="指导总价(元)" prop="guidanceTotalPrice">
              <el-input-number
                v-model="formData.guidanceTotalPrice"
                :min="0"
                :precision="2"
                :step="1000"
                class="!w-1/1"
                controls-position="right"
              />
            </el-form-item>
          </el-col>
        </el-row>
      </template>
    </el-form>
    <template #footer>
      <el-button :disabled="formLoading" 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 {
  CALCULATION_METHOD_OPTIONS,
  DEFAULT_WORKING_DAY_UNIT_PRICE,
  DESIGN_STAGE_OPTIONS,
  OWNERSHIP_TYPE_OPTIONS,
  VIRTUAL_CALCULATION_METHOD_OPTIONS,
  formatAmountText,
  formatPercentText,
  fromPercentValue,
  getCalculationRatioDefaultPercent,
  getCalculationRatioLabel,
  getReviewOutsourceDefaultPercent,
  isComprehensiveOwnership,
  isContractPriceMethod,
  isGuidancePriceMethod,
  isMajorOwnership,
  isSubcontractOwnership,
  isVirtualGuidanceMethod,
  isVirtualGuidanceTotalPriceMethod,
  isVirtualOutputMethod,
  isWorkingDayMethod,
  normalizeCalculationMethod,
  normalizeDesignStage,
  normalizeOwnershipType,
  normalizeVirtualCalculationMethod,
  toPercentValue
} from '@/views/tjt/shared/planning'

defineOptions({ name: 'TjtPlanningOutputForm' })

const DESIGN_PART_OPTIONS = [
  { label: '地上部分', value: '地上部分' },
  { label: '地下部分', value: '地下部分' }
]

const OWNERSHIP_TYPE_LABELS = ['专业所', '综合所', '专业分包']
const CALCULATION_METHOD_LABELS = ['指导价法', '合同价法', '虚拟产值法']
const DESIGN_STAGE_LABELS = ['方案', '施工图', '方案+施工图']
const VIRTUAL_CALCULATION_METHOD_LABELS = ['指导单价法', '指导总价法', '工日法']

const createDisplayOptions = (
  source: Array<{ label: string; value: string }>,
  labels: string[]
) => source.map((item, index) => ({ label: labels[index] || item.label, value: item.value }))

const ownershipTypeOptions = createDisplayOptions(OWNERSHIP_TYPE_OPTIONS, OWNERSHIP_TYPE_LABELS)
const calculationMethodOptions = createDisplayOptions(
  CALCULATION_METHOD_OPTIONS,
  CALCULATION_METHOD_LABELS
)
const designStageOptions = createDisplayOptions(DESIGN_STAGE_OPTIONS, DESIGN_STAGE_LABELS)
const virtualCalculationMethodOptions = createDisplayOptions(
  VIRTUAL_CALCULATION_METHOD_OPTIONS,
  VIRTUAL_CALCULATION_METHOD_LABELS
)

const { t } = useI18n()
const message = useMessage()

const dialogVisible = ref(false)
const dialogTitle = ref('')
const formLoading = ref(false)
const formRef = ref()
const formData = ref<PlanningApi.ProjectPlanningVO>({
  projectId: 0,
  ownershipType: '',
  calculationMethod: '',
  planningContent: ''
})

const getOptionLabel = (options: Array<{ label: string; value: string }>, value?: string) =>
  options.find((item) => item.value === value)?.label || value || ''

const ownershipTypeLabel = computed(() =>
  getOptionLabel(ownershipTypeOptions, formData.value.ownershipType)
)

const normalizeFormData = (data: PlanningApi.ProjectPlanningVO): PlanningApi.ProjectPlanningVO => ({
  ...data,
  ownershipType: normalizeOwnershipType(data.ownershipType) || data.ownershipType || '',
  calculationMethod: normalizeCalculationMethod(data.calculationMethod) || data.calculationMethod || '',
  designPart: DESIGN_PART_OPTIONS.find((item) => item.value === data.designPart)?.value || undefined,
  designStage: normalizeDesignStage(data.designStage),
  virtualCalculationMethod: normalizeVirtualCalculationMethod(data.virtualCalculationMethod),
  reviewOutsourceFlag: data.reviewOutsourceFlag ?? false,
  totalDistributionAmount: data.totalDistributionAmount ?? 1,
  progressRemark: data.progressRemark ?? '',
  drawingSetFactor: data.drawingSetFactor ?? 1,
  scaleFactor: data.scaleFactor ?? 1,
  modificationFactor: data.modificationFactor ?? 1,
  complexityFactor: data.complexityFactor ?? 1,
  workingDayUnitPrice:
    data.workingDayUnitPrice ??
    (isWorkingDayMethod(data.virtualCalculationMethod) ? DEFAULT_WORKING_DAY_UNIT_PRICE : undefined),
  guidanceTotalPrice: data.guidanceTotalPrice
})

const planningStartYearValue = computed({
  get: () =>
    formData.value.planningStartYear ? String(formData.value.planningStartYear) : undefined,
  set: (value?: string) => {
    formData.value.planningStartYear = value ? Number(value) : undefined
  }
})

const contractUnitPricePreview = computed(() => {
  const planningAmount = Number(formData.value.planningAmount || 0)
  const planningArea = Number(formData.value.planningArea || 0)
  if (!planningArea) {
    return formatAmountText(0)
  }
  return formatAmountText(planningAmount / planningArea)
})

const createPercentModel = (field: keyof PlanningApi.ProjectPlanningVO, digits = 2) =>
  computed({
    get: () => toPercentValue(formData.value[field] as number | undefined, digits),
    set: (value) => {
      formData.value[field] = fromPercentValue(value, 4) as never
    }
  })

const currentDesignStageRatioPercent = createPercentModel('currentDesignStageRatio')
const reviewOutsourceRatioPercent = createPercentModel('reviewOutsourceRatio')
const calculationRatioPercent = createPercentModel('calculationRatio')
const totalDistributionAmountPercent = createPercentModel('totalDistributionAmount')
const complexityFactorPercent = createPercentModel('complexityFactor')

const showCalculationRatioField = computed(
  () =>
    isComprehensiveOwnership(formData.value.ownershipType) ||
    isSubcontractOwnership(formData.value.ownershipType)
)
const calculationRatioLabel = computed(() => getCalculationRatioLabel(formData.value.ownershipType))
const showMajorFactorFields = computed(
  () =>
    isMajorOwnership(formData.value.ownershipType) &&
    (isGuidancePriceMethod(formData.value.calculationMethod) ||
      isContractPriceMethod(formData.value.calculationMethod))
)
const showInternalGuidanceUnitPriceField = computed(
  () =>
    isMajorOwnership(formData.value.ownershipType) &&
    isGuidancePriceMethod(formData.value.calculationMethod)
)
const showVirtualOutputSection = computed(
  () =>
    isMajorOwnership(formData.value.ownershipType) &&
    isVirtualOutputMethod(formData.value.calculationMethod)
)
const showWorkingDayFields = computed(() => isWorkingDayMethod(formData.value.virtualCalculationMethod))
const showGuidanceUnitPriceField = computed(
  () => isVirtualGuidanceMethod(formData.value.virtualCalculationMethod)
)
const showGuidanceTotalPriceField = computed(
  () => isVirtualGuidanceTotalPriceMethod(formData.value.virtualCalculationMethod)
)

const formRules = reactive<FormRules>({
  calculationMethod: [{ required: true, message: '产值计算方式不能为空', trigger: 'change' }],
  designPart: [{ required: true, message: '设计部位不能为空', trigger: 'change' }],
  buildingType: [{ required: true, message: '建筑类型不能为空', trigger: 'blur' }],
  planningStartYear: [{ required: true, message: '开始年度不能为空', trigger: 'change' }],
  planningArea: [{ required: true, message: '工程总面积不能为空', trigger: 'blur' }],
  designStage: [{ required: true, message: '设计阶段不能为空', trigger: 'change' }],
  currentDesignStageRatio: [
    { required: true, message: '本次设计阶段比例不能为空', trigger: 'blur' }
  ],
  totalDistributionAmount: [{ required: true, message: '总分配不能为空', trigger: 'blur' }],
  calculationRatio: [
    {
      validator: (_rule, value, callback) => {
        if (showCalculationRatioField.value && (value === undefined || value === null || value === '')) {
          callback(new Error(`${calculationRatioLabel.value}不能为空`))
          return
        }
        callback()
      },
      trigger: 'blur'
    }
  ],
  internalGuidanceUnitPrice: [
    {
      validator: (_rule, value, callback) => {
        if (
          showInternalGuidanceUnitPriceField.value &&
          (value === undefined || value === null || value === '')
        ) {
          callback(new Error('内部指导单价不能为空'))
          return
        }
        callback()
      },
      trigger: 'blur'
    }
  ],
  virtualCalculationMethod: [
    {
      validator: (_rule, value, callback) => {
        if (showVirtualOutputSection.value && !value) {
          callback(new Error('请选择虚拟产值计算方式'))
          return
        }
        callback()
      },
      trigger: 'change'
    }
  ],
  workingDayCount: [
    {
      validator: (_rule, value, callback) => {
        if (showWorkingDayFields.value && (value === undefined || value === null || value === '')) {
          callback(new Error('工日不能为空'))
          return
        }
        callback()
      },
      trigger: 'blur'
    }
  ],
  workingDayUnitPrice: [
    {
      validator: (_rule, value, callback) => {
        if (showWorkingDayFields.value && (value === undefined || value === null || value === '')) {
          callback(new Error('工日单价不能为空'))
          return
        }
        callback()
      },
      trigger: 'blur'
    }
  ],
  guidanceUnitPrice: [
    {
      validator: (_rule, value, callback) => {
        if (
          showGuidanceUnitPriceField.value &&
          (value === undefined || value === null || value === '')
        ) {
          callback(new Error('指导单价不能为空'))
          return
        }
        callback()
      },
      trigger: 'blur'
    }
  ],
  guidanceTotalPrice: [
    {
      validator: (_rule, value, callback) => {
        if (
          showGuidanceTotalPriceField.value &&
          (value === undefined || value === null || value === '')
        ) {
          callback(new Error('指导总价不能为空'))
          return
        }
        callback()
      },
      trigger: 'blur'
    }
  ]
})

const applyReviewOutsourceDefault = () => {
  formData.value.reviewOutsourceRatio = fromPercentValue(
    getReviewOutsourceDefaultPercent(
      formData.value.ownershipType,
      formData.value.reviewOutsourceFlag
    )
  )
}

const applyCalculationRatioDefault = () => {
  const defaultPercent = getCalculationRatioDefaultPercent(formData.value.ownershipType)
  if (defaultPercent === undefined) {
    return
  }
  if (formData.value.calculationRatio === undefined || formData.value.calculationRatio === null) {
    formData.value.calculationRatio = fromPercentValue(defaultPercent)
  }
}

const handleReviewOutsourceFlagChange = () => {
  applyReviewOutsourceDefault()
}

watch(
  () => formData.value.virtualCalculationMethod,
  (value) => {
    if (
      isWorkingDayMethod(value) &&
      (formData.value.workingDayUnitPrice === undefined || formData.value.workingDayUnitPrice === null)
    ) {
      formData.value.workingDayUnitPrice = DEFAULT_WORKING_DAY_UNIT_PRICE
    }
  }
)

const buildSavePayload = (): PlanningApi.ProjectPlanningSaveVO => ({
  id: formData.value.id,
  projectId: formData.value.projectId,
  ownershipType: formData.value.ownershipType,
  designPart: formData.value.designPart,
  buildingType: formData.value.buildingType,
  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
})

const open = async (id: number) => {
  dialogVisible.value = true
  dialogTitle.value = t('action.update')
  formLoading.value = true
  try {
    const data = await PlanningApi.getProjectPlanning(id)
    formData.value = normalizeFormData(data)
    applyCalculationRatioDefault()
    if (formData.value.reviewOutsourceRatio === undefined || formData.value.reviewOutsourceRatio === null) {
      applyReviewOutsourceDefault()
    }
  } finally {
    formLoading.value = false
  }
}
defineExpose({ open })

const emit = defineEmits(['success'])

const submitForm = async () => {
  if (!formRef.value) {
    return
  }
  const valid = await formRef.value.validate()
  if (!valid) {
    return
  }
  formLoading.value = true
  try {
    await PlanningApi.updateProjectPlanning(buildSavePayload())
    message.success(t('common.updateSuccess'))
    dialogVisible.value = false
    emit('success')
  } finally {
    formLoading.value = false
  }
}
</script>
