<template>
  <ContentWrap>
    <el-form
      ref="queryFormRef"
      :inline="true"
      :model="queryParams"
      class="-mb-15px"
      label-width="88px"
    >
      <el-form-item label="项目名称" prop="projectName">
        <el-input
          v-model="queryParams.projectName"
          class="!w-240px"
          clearable
          placeholder="请输入项目名称"
          @keyup.enter="handleQuery"
        />
      </el-form-item>
      <el-form-item label="开始年度" prop="projectStartYear">
        <el-date-picker
          v-model="queryProjectStartYearValue"
          class="!w-180px"
          clearable
          placeholder="请选择年度"
          type="year"
          value-format="YYYY"
        />
      </el-form-item>
      <el-form-item>
        <el-button @click="handleQuery">
          <Icon class="mr-5px" icon="ep:search" />
          搜索
        </el-button>
        <el-button @click="resetQuery">
          <Icon class="mr-5px" icon="ep:refresh" />
          重置
        </el-button>
      </el-form-item>
    </el-form>
  </ContentWrap>

  <ContentWrap>
    <el-table
      ref="projectTableRef"
      v-loading="loading"
      :data="projectList"
      highlight-current-row
      @current-change="handleCurrentProjectChange"
    >
      <el-table-column
        :index="getProjectRowIndex"
        align="center"
        label="序号"
        type="index"
        width="80"
      />
      <el-table-column align="center" label="项目名称" min-width="220" prop="projectName" />
      <el-table-column align="center" label="工程负责人" min-width="180">
        <template #default="scope">
          {{ getProjectLeadText(scope.row.projectManagerName, scope.row.engineeringPrincipalName) }}
        </template>
      </el-table-column>
      <el-table-column align="center" label="开始年度" prop="projectStartYear" width="120" />
      <el-table-column align="center" label="排序" prop="sortNo" width="80" />
    </el-table>
    <Pagination
      v-model:limit="queryParams.pageSize"
      v-model:page="queryParams.pageNo"
      :total="total"
      @pagination="getProjectList"
    />
  </ContentWrap>

  <SplitPane>
    <template #left>
      <ContentWrap>
        <div class="mb-12px text-14px font-600">
          {{ currentProject?.projectName || '合约规划列表' }}
        </div>
        <el-table
          ref="planningTableRef"
          v-loading="planningLoading"
          :data="planningList"
          highlight-current-row
          @current-change="handleCurrentPlanningChange"
        >
          <el-table-column align="center" label="项目任务包" min-width="180" prop="planningContent" />
          <el-table-column align="center" label="归属类型" min-width="110">
            <template #default="scope">
              {{ getOwnershipTypeLabel(scope.row.ownershipType) }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="开始年度" prop="planningStartYear" width="100" />
          <el-table-column align="center" label="考核产值(元)" width="120">
            <template #default="scope">
              {{ formatAmountText(scope.row.assessmentOutputValue) }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="排序" prop="sortNo" width="80" />
        </el-table>
      </ContentWrap>
    </template>

    <template #right>
      <ContentWrap>
        <div v-loading="quarterLoading" class="min-h-320px">
          <template v-if="currentPlanning && formData">
        <div class="mb-16px flex items-center justify-between gap-16px">
          <div>
            <div class="text-16px font-600">{{ currentPlanning.planningContent }}</div>
          </div>
          <div class="flex items-center gap-12px">
            <el-button
              v-hasPermi="['tjt:report-project-quarter:export']"
              :loading="exportQuarterLoading"
              plain
              type="success"
              @click="handleExportProjectQuarter"
            >
              <Icon class="mr-5px" icon="ep:download" />
              导出专业间年度季度计取表
            </el-button>
            <el-button
              v-hasPermi="['tjt:report-project-quarter:export']"
              :loading="exportLeadLoading"
              plain
              type="success"
              @click="handleExportProjectLeadQuarter"
            >
              <Icon class="mr-5px" icon="ep:download" />
              导出工程负责人计取表
            </el-button>
          </div>
        </div>

        <el-descriptions :column="2" border title="基础信息">
          <el-descriptions-item label="项目名称">{{ formData.projectName || '-' }}</el-descriptions-item>
          <el-descriptions-item label="项目任务包">{{ formData.planningContent || '-' }}</el-descriptions-item>
          <el-descriptions-item label="工程负责人">
            {{ getProjectLeadText(formData.projectManagerName, formData.engineeringLeaderName) }}
          </el-descriptions-item>
          <el-descriptions-item label="考核产值(元)">
            {{ formatAmountText(formData.assessmentOutputValue) }}
          </el-descriptions-item>
        </el-descriptions>

        <el-divider content-position="left">项目层结果</el-divider>
        <el-table :data="projectResultRows" border>
          <el-table-column align="center" label="类别" min-width="160" prop="label" />
          <el-table-column align="center" label="比例" min-width="120">
            <template #default="scope">
              {{ scope.row.percentText }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="金额(元)" min-width="140">
            <template #default="scope">
              {{ formatAmountText(scope.row.amount) }}
            </template>
          </el-table-column>
        </el-table>

        <el-divider content-position="left">专业层结果</el-divider>
        <el-table :data="specialtyResultRows" border>
          <el-table-column align="center" label="专业" min-width="140" prop="label" />
          <el-table-column align="center" label="比例" min-width="120">
            <template #default="scope">
              {{ scope.row.percentText }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="金额(元)" min-width="140">
            <template #default="scope">
              {{ formatAmountText(scope.row.amount) }}
            </template>
          </el-table-column>
        </el-table>

        <el-divider content-position="left">年度分配信息</el-divider>
        <div class="mb-12px">
          <el-radio-group v-model="selectedAnnualCategory" size="small">
            <el-radio-button
              v-for="item in annualCategoryOptions"
              :key="item.value"
              :label="item.value"
            >
              {{ item.label }}
            </el-radio-button>
          </el-radio-group>
        </div>
        <el-row :gutter="16" class="mb-16px">
          <el-col v-for="item in annualSummaryCards" :key="item.label" :span="8">
            <div class="rounded-8px bg-[var(--el-fill-color-light)] px-16px py-12px">
              <div class="text-12px text-[var(--el-text-color-secondary)]">{{ item.label }}</div>
              <div class="mt-6px text-18px font-600">{{ formatAmountText(item.amount) }}</div>
            </div>
          </el-col>
        </el-row>
        <el-table :data="annualDistributionRows" border>
          <el-table-column align="center" label="分配年度" min-width="120" prop="distributionYear" />
          <el-table-column
            v-for="quarter in QUARTER_OPTIONS"
            :key="String(quarter.value)"
            align="center"
            :label="quarter.label"
            min-width="150"
          >
            <template #default="scope">
              {{ formatAmountText(scope.row.quarterAmounts[Number(quarter.value)]) }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="年度合计(元)" min-width="160">
            <template #default="scope">
              {{ formatAmountText(scope.row.yearTotal) }}
            </template>
          </el-table-column>
        </el-table>
          </template>

          <el-empty v-else-if="!quarterLoading" description="请选择合约规划后查看导出预览" />
        </div>
      </ContentWrap>
    </template>
  </SplitPane>

  <Dialog v-model="exportDialogVisible" :title="exportDialogTitle" width="420">
    <el-form label-width="88px">
      <el-form-item label="年度">
        <el-date-picker
          v-model="exportYearValue"
          class="!w-220px"
          clearable
          placeholder="请选择年度"
          type="year"
          value-format="YYYY"
        />
      </el-form-item>
    </el-form>

    <template #footer>
      <el-button @click="exportDialogVisible = false">取消</el-button>
      <el-button :loading="currentExportLoading" type="primary" @click="submitExport">
        确定导出
      </el-button>
    </template>
  </Dialog>
</template>

<script lang="ts" setup>
import * as OutputSplitApi from '@/api/tjt/outputSplit'
import * as PlanningApi from '@/api/tjt/planning'
import * as PlanningQuarterApi from '@/api/tjt/planningQuarter'
import * as ProjectApi from '@/api/tjt/project'
import * as ReportApi from '@/api/tjt/report'
import download from '@/utils/download'
import SplitPane from '@/views/tjt/shared/SplitPane.vue'
import {
  formatAmountText,
  getOwnershipTypeLabel,
  OUTPUT_SPLIT_SPECIALTY,
  OUTPUT_SPLIT_SPECIALTY_OPTIONS,
  QUARTER_OPTIONS,
  toPercentValue
} from '@/views/tjt/shared/planning'

defineOptions({ name: 'TjtReportProjectQuarter' })

type AnnualCategoryKey = (typeof OUTPUT_SPLIT_SPECIALTY)[keyof typeof OUTPUT_SPLIT_SPECIALTY]

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

type ExportDialogType = 'projectQuarter' | 'projectLeadQuarter'

const annualCategoryOptions: { label: string; value: AnnualCategoryKey }[] = [
  { label: '项目经理/工程负责人', value: OUTPUT_SPLIT_SPECIALTY.projectLead },
  { label: '建筑专业', value: OUTPUT_SPLIT_SPECIALTY.arch },
  { label: '装修专业', value: OUTPUT_SPLIT_SPECIALTY.decor },
  { label: '结构专业', value: OUTPUT_SPLIT_SPECIALTY.struct },
  { label: '水专业', value: OUTPUT_SPLIT_SPECIALTY.water },
  { label: '电气专业', value: OUTPUT_SPLIT_SPECIALTY.elec },
  { label: '暖通专业', value: OUTPUT_SPLIT_SPECIALTY.hvac },
  { label: '数字化设计专业', value: OUTPUT_SPLIT_SPECIALTY.digital }
]

const message = useMessage()
const currentYear = new Date().getFullYear()

const loading = ref(false)
const planningLoading = ref(false)
const quarterLoading = ref(false)
const exportQuarterLoading = ref(false)
const exportLeadLoading = ref(false)
const exportDialogVisible = ref(false)
const exportDialogType = ref<ExportDialogType>('projectQuarter')
const exportYear = ref<number>()
const total = ref(0)
const projectList = ref<ProjectApi.ProjectVO[]>([])
const planningList = ref<PlanningApi.ProjectPlanningVO[]>([])
const currentProject = ref<ProjectApi.ProjectVO>()
const currentPlanning = ref<PlanningApi.ProjectPlanningVO>()
const formData = ref<OutputSplitApi.ProjectOutputSplitVO>()
const quarterRows = ref<QuarterYearRow[]>([])
const selectedAnnualCategory = ref<AnnualCategoryKey>(OUTPUT_SPLIT_SPECIALTY.projectLead)
const queryFormRef = ref()
const projectTableRef = ref()
const planningTableRef = ref()

const queryParams = reactive<ProjectApi.ProjectPageReqVO>({
  pageNo: 1,
  pageSize: 10,
  projectName: undefined,
  projectStartYear: undefined
})

const getProjectRowIndex = (index: number) =>
  (queryParams.pageNo - 1) * queryParams.pageSize + index + 1

const queryProjectStartYearValue = computed({
  get: () => (queryParams.projectStartYear ? String(queryParams.projectStartYear) : undefined),
  set: (value?: string) => {
    queryParams.projectStartYear = value ? Number(value) : undefined
  }
})

const exportDialogTitle = computed(() =>
  exportDialogType.value === 'projectQuarter' ? '导出专业间年度季度计取表' : '导出工程负责人计取表'
)

const currentExportLoading = computed(() =>
  exportDialogType.value === 'projectQuarter'
    ? exportQuarterLoading.value
    : exportLeadLoading.value
)

const exportYearValue = computed({
  get: () => (exportYear.value ? String(exportYear.value) : undefined),
  set: (value?: string) => {
    exportYear.value = value ? Number(value) : undefined
  }
})

const toNumeric = (value?: number | string | null) => {
  const numericValue = Number(value ?? 0)
  return Number.isNaN(numericValue) ? 0 : numericValue
}

const multiplyAmount = (...values: Array<number | string | null | undefined>) => {
  let result = 1
  values.forEach((value) => {
    result *= toNumeric(value)
  })
  return Number(result.toFixed(2))
}

const formatRatioText = (value?: number | string | null) =>
  `${(toPercentValue(value) ?? 0).toFixed(2)}%`

const getRatioValue = (model: OutputSplitApi.ProjectOutputSplitVO, key: string) =>
  (model as unknown as Record<string, number | undefined>)[key]

const getProjectLeadText = (projectManagerName?: string, engineeringLeaderName?: string) =>
  [projectManagerName, engineeringLeaderName].filter(Boolean).join(' / ') || '-'

const buildProjectRows = (model?: OutputSplitApi.ProjectOutputSplitVO) => {
  if (!model) {
    return []
  }
  return [
    {
      label: '项目经理/工程负责人',
      percentText: formatRatioText(model.projectLeadRatio),
      amount: model.projectLeadAmount
    },
    {
      label: '专业所',
      percentText: formatRatioText(model.officeRatio),
      amount: model.officeAmount
    }
  ]
}

const buildSpecialtyRows = (model?: OutputSplitApi.ProjectOutputSplitVO) => {
  if (!model) {
    return []
  }
  const amountMap: Record<string, number | undefined> = {
    arch: model.archAmount,
    decor: model.decorAmount,
    struct: model.structAmount,
    water: model.waterAmount,
    elec: model.elecAmount,
    hvac: model.hvacAmount,
    digital: model.digitalAmount
  }
  return OUTPUT_SPLIT_SPECIALTY_OPTIONS.map((item) => ({
    label: item.label,
    percentText: formatRatioText(getRatioValue(model, `${item.value}Ratio`)),
    amount: amountMap[item.value]
  }))
}

const projectResultRows = computed(() => buildProjectRows(formData.value))
const specialtyResultRows = computed(() => buildSpecialtyRows(formData.value))

const annualCategoryMeta = computed(() => {
  const model = formData.value
  const option = annualCategoryOptions.find((item) => item.value === selectedAnnualCategory.value)
  if (!model || !option) {
    return { ratio: 0 }
  }
  if (selectedAnnualCategory.value === OUTPUT_SPLIT_SPECIALTY.projectLead) {
    return {
      ratio: Number(toNumeric(model.projectLeadRatio).toFixed(4))
    }
  }
  const specialtyRatio = toNumeric(getRatioValue(model, `${selectedAnnualCategory.value}Ratio`))
  return {
    ratio: Number((toNumeric(model.officeRatio) * specialtyRatio).toFixed(4))
  }
})

const annualDistributionRows = computed(() =>
  quarterRows.value.map((row) => {
    const quarterAmounts: Record<number, number> = {}
    let yearTotal = 0
    QUARTER_OPTIONS.forEach((quarter) => {
      const quarterNo = Number(quarter.value)
      const quarterAmount = multiplyAmount(
        row.quarters.find((item) => item.quarterNo === quarterNo)?.distributionAmount,
        annualCategoryMeta.value.ratio
      )
      quarterAmounts[quarterNo] = quarterAmount
      yearTotal += quarterAmount
    })
    return {
      distributionYear: row.distributionYear,
      quarterAmounts,
      yearTotal: Number(yearTotal.toFixed(2))
    }
  })
)

const annualSummaryCards = computed(() => [
  {
    label: '总分配',
    amount: multiplyAmount(
      currentPlanning.value?.assessmentOutputValue,
      currentPlanning.value?.totalDistributionAmount,
      annualCategoryMeta.value.ratio
    )
  },
  {
    label: '已分配',
    amount: multiplyAmount(
      currentPlanning.value?.assessmentOutputValue,
      currentPlanning.value?.allocatedAmount,
      annualCategoryMeta.value.ratio
    )
  },
  {
    label: '待分配',
    amount: multiplyAmount(
      currentPlanning.value?.assessmentOutputValue,
      currentPlanning.value?.pendingAmount,
      annualCategoryMeta.value.ratio
    )
  }
])

const buildQuarterRows = (
  planning: PlanningApi.ProjectPlanningVO,
  quarters: PlanningQuarterApi.ProjectPlanningQuarterVO[]
) => {
  const yearSet = new Set<number>()
  if (planning.planningStartYear) {
    yearSet.add(planning.planningStartYear)
  }
  quarters.forEach((item) => yearSet.add(item.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) =>
            item.distributionYear === distributionYear && Number(item.quarterNo) === quarterNo
        )
        return (
          match || {
            planningId: planning.id!,
            distributionYear,
            quarterNo,
            distributionRatio: undefined,
            distributionAmount: 0
          }
        )
      })
    }))
}

const getProjectList = async () => {
  loading.value = true
  try {
    const data = await ProjectApi.getProjectPage(queryParams)
    projectList.value = data.list
    total.value = data.total
    if (!projectList.value.length) {
      currentProject.value = undefined
      planningList.value = []
      currentPlanning.value = undefined
      formData.value = undefined
      quarterRows.value = []
      return
    }
    const targetProjectId = currentProject.value?.id || projectList.value[0].id
    const targetProject =
      projectList.value.find((item) => item.id === targetProjectId) || projectList.value[0]
    await nextTick()
    projectTableRef.value?.setCurrentRow(targetProject)
  } finally {
    loading.value = false
  }
}

const getPlanningList = async () => {
  if (!currentProject.value?.id) {
    planningList.value = []
    currentPlanning.value = undefined
    formData.value = undefined
    quarterRows.value = []
    return
  }
  planningLoading.value = true
  try {
    const list = await PlanningApi.getProjectPlanningListByProjectId(currentProject.value.id)
    planningList.value = list
    if (!planningList.value.length) {
      currentPlanning.value = undefined
      formData.value = undefined
      quarterRows.value = []
      return
    }
    const targetPlanningId = currentPlanning.value?.id || planningList.value[0].id
    const targetPlanning =
      planningList.value.find((item) => item.id === targetPlanningId) || planningList.value[0]
    await nextTick()
    planningTableRef.value?.setCurrentRow(targetPlanning)
  } finally {
    planningLoading.value = false
  }
}

const loadPlanningRelatedData = async (planning: PlanningApi.ProjectPlanningVO) => {
  if (!planning.id) {
    return
  }
  quarterLoading.value = true
  try {
    const detail = await OutputSplitApi.getProjectOutputSplitPlanningDetail(planning.id)
    currentPlanning.value = detail?.planning
    formData.value = detail?.outputSplit
    quarterRows.value = detail?.planning
      ? buildQuarterRows(detail.planning, detail.quarters || [])
      : []
  } finally {
    quarterLoading.value = false
  }
}

const handleQuery = () => {
  queryParams.pageNo = 1
  getProjectList()
}

const resetQuery = () => {
  queryFormRef.value?.resetFields()
  handleQuery()
}

const handleCurrentProjectChange = async (row?: ProjectApi.ProjectVO) => {
  currentProject.value = row || undefined
  await getPlanningList()
}

const handleCurrentPlanningChange = async (row?: PlanningApi.ProjectPlanningVO) => {
  currentPlanning.value = row || undefined
  if (!row?.id) {
    formData.value = undefined
    quarterRows.value = []
    return
  }
  await loadPlanningRelatedData(row)
}

const handleExportProjectQuarter = async () => {
  if (!currentPlanning.value?.id) {
    message.warning('请先选择合约规划')
    return
  }
  exportDialogType.value = 'projectQuarter'
  exportYear.value = currentPlanning.value.planningStartYear || currentYear
  exportDialogVisible.value = true
}

const handleExportProjectLeadQuarter = async () => {
  if (!currentPlanning.value?.id) {
    message.warning('请先选择合约规划')
    return
  }
  exportDialogType.value = 'projectLeadQuarter'
  exportYear.value = currentPlanning.value.planningStartYear || currentYear
  exportDialogVisible.value = true
}

const submitExport = async () => {
  if (exportDialogType.value === 'projectQuarter') {
    await submitProjectQuarterExport()
    return
  }
  await submitProjectLeadQuarterExport()
}

const submitProjectQuarterExport = async () => {
  if (!currentPlanning.value?.id) {
    message.warning('请先选择合约规划')
    return
  }
  if (!exportYear.value) {
    message.warning('请选择年度')
    return
  }
  try {
    await message.exportConfirm()
    exportQuarterLoading.value = true
    const data = await ReportApi.exportProjectQuarterOutput({
      planningId: currentPlanning.value.id,
      year: exportYear.value
    })
    download.excel(
      data,
      `${currentProject.value?.projectName || '项目'}_${exportYear.value}_专业间年度季度计取表.xlsx`
    )
    exportDialogVisible.value = false
  } finally {
    exportQuarterLoading.value = false
  }
}

const submitProjectLeadQuarterExport = async () => {
  if (!currentPlanning.value?.id) {
    message.warning('请先选择合约规划')
    return
  }
  if (!exportYear.value) {
    message.warning('请选择年度')
    return
  }
  try {
    await message.exportConfirm()
    exportLeadLoading.value = true
    const data = await ReportApi.exportProjectLeadQuarterOutput({
      planningId: currentPlanning.value.id,
      year: exportYear.value
    })
    download.excel(
      data,
      `${currentProject.value?.projectName || '项目'}_${exportYear.value}_工程负责人年度季度计取表.xlsx`
    )
    exportDialogVisible.value = false
  } finally {
    exportLeadLoading.value = false
  }
}

let activatedOnce = false

onMounted(() => {
  getProjectList()
})

onActivated(() => {
  // KeepAlive 首次挂载也会触发 onActivated，跳过首轮避免重复请求项目与合约规划列表。
  if (!activatedOnce) {
    activatedOnce = true
    return
  }
  getProjectList()
})
</script>
