<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 align="center" label="项目ID" prop="id" width="88" />
      <el-table-column align="center" label="工程名称" min-width="220" prop="projectName" />
      <el-table-column align="center" label="项目经理" min-width="120" prop="projectManagerName" />
      <el-table-column
        align="center"
        label="项目负责人"
        min-width="120"
        prop="engineeringPrincipalName"
      />
      <el-table-column align="center" label="开始年度" prop="projectStartYear" width="120" />
    </el-table>
    <Pagination
      v-model:limit="queryParams.pageSize"
      v-model:page="queryParams.pageNo"
      :total="total"
      @pagination="getProjectList"
    />
  </ContentWrap>

  <el-row :gutter="16">
    <el-col :span="8">
      <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>
      </ContentWrap>
    </el-col>

    <el-col :span="16">
      <ContentWrap v-if="currentPlanning && currentGroup">
        <div class="mb-16px flex items-center justify-between gap-12px">
          <div>
            <div class="text-16px font-600">{{ currentPlanning.planningContent }}</div>
          </div>
          <el-button
            v-hasPermi="['tjt:report-specialty-person:export']"
            :disabled="!canExportCurrentGroup"
            :loading="exportSpecialtyLoading"
            plain
            type="success"
            @click="handleExportSpecialtyPerson"
          >
            <Icon class="mr-5px" icon="ep:download" />
            导出专业内人员计取表
          </el-button>
        </div>

        <div class="mb-16px">
          <el-radio-group v-model="selectedGroupCode" size="small">
            <el-radio-button v-for="item in groupTabOptions" :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 buildSummaryCards(currentGroup)" :key="item.label" :span="6">
            <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">{{ item.value }}</div>
            </div>
          </el-col>
        </el-row>

        <el-table :data="currentGroup.rows" border>
          <el-table-column align="center" label="角色" min-width="110" prop="roleName" />
          <el-table-column align="center" label="角色比例" min-width="120">
            <template #default="scope">
              {{ formatPercentText(scope.row.roleRatio) }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="角色金额(元)" min-width="130">
            <template #default="scope">
              {{ formatAmountText(scope.row.roleAmount) }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="人员合计" min-width="120">
            <template #default="scope">
              {{ formatPercentText(getPersonTotalRatio(scope.row)) }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="人员信息" min-width="360">
            <template #default="scope">
              <div v-if="scope.row.persons?.length" class="person-display-list">
                <div
                  v-for="(person, index) in scope.row.persons"
                  :key="`${scope.row.specialtyCode}-${scope.row.roleCode}-display-${index}`"
                  class="person-display-row"
                >
                  <span class="person-display-name">{{ person.employeeName || '-' }}</span>
                  <span>{{ formatPercentText(person.personRatio) }}</span>
                  <span>{{ formatAmountText(person.personAmount) }} 元</span>
                </div>
              </div>
              <div v-else class="person-empty">暂无人员</div>
            </template>
          </el-table-column>
        </el-table>
      </ContentWrap>

      <ContentWrap v-else>
        <el-empty description="请选择合约规划后查看导出预览" />
      </ContentWrap>
    </el-col>
  </el-row>
</template>

<script lang="ts" setup>
import * as PlanningApi from '@/api/tjt/planning'
import * as ProjectApi from '@/api/tjt/project'
import * as ReportApi from '@/api/tjt/report'
import * as SpecialtyRoleSplitApi from '@/api/tjt/specialtyRoleSplit'
import download from '@/utils/download'
import { formatAmountText, formatPercentText, getOwnershipTypeLabel } from '@/views/tjt/shared/planning'

defineOptions({ name: 'TjtReportSpecialtyPerson' })

const PROJECT_LEAD_GROUP_CODE = 'project_lead'
const EPSILON = 0.0001

type SpecialtyRoleSplitVO = SpecialtyRoleSplitApi.SpecialtyRoleSplitVO

interface SpecialtyGroup {
  specialtyCode: string
  specialtyName: string
  specialtyAmount: number
  rows: SpecialtyRoleSplitVO[]
  roleTotal: number
  personCount: number
}

const message = useMessage()

const loading = ref(false)
const planningLoading = ref(false)
const exportSpecialtyLoading = ref(false)
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 roleList = ref<SpecialtyRoleSplitVO[]>([])
const selectedGroupCode = ref('')
const queryFormRef = ref()
const projectTableRef = ref()
const planningTableRef = ref()

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

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

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

const countConfiguredPersons = (persons?: SpecialtyRoleSplitApi.SpecialtyRolePersonVO[]) =>
  (persons || []).filter(
    (person) =>
      (person.employeeName && person.employeeName.trim()) ||
      (person.personRatio !== undefined && person.personRatio !== null)
  ).length

const getPersonTotalRatio = (row: SpecialtyRoleSplitVO) =>
  roundRatio((row.persons || []).reduce((sum, person) => sum + Number(person?.personRatio || 0), 0))

const buildGroups = (source: SpecialtyRoleSplitVO[]): SpecialtyGroup[] => {
  const map = new Map<string, SpecialtyRoleSplitVO[]>()
  source.forEach((item) => {
    const list = map.get(item.specialtyCode) || []
    list.push(item)
    map.set(item.specialtyCode, list)
  })
  return Array.from(map.entries()).map(([specialtyCode, rows]) => {
    const sortedRows = [...rows].sort((a, b) => Number(a.sortNo || 0) - Number(b.sortNo || 0))
    return {
      specialtyCode,
      specialtyName: sortedRows[0]?.specialtyName || specialtyCode,
      specialtyAmount: Number(Number(sortedRows[0]?.specialtyAmount || 0).toFixed(2)),
      rows: sortedRows,
      roleTotal: roundRatio(sortedRows.reduce((sum, item) => sum + Number(item.roleRatio || 0), 0)),
      personCount: sortedRows.reduce((sum, row) => sum + countConfiguredPersons(row.persons), 0)
    }
  })
}

const groups = computed(() => buildGroups(roleList.value))
const groupTabOptions = computed(() =>
  groups.value.map((item) => ({
    label: item.specialtyName,
    value: item.specialtyCode
  }))
)
const currentGroup = computed(
  () => groups.value.find((item) => item.specialtyCode === selectedGroupCode.value) || groups.value[0]
)
const canExportCurrentGroup = computed(
  () =>
    !!currentGroup.value?.specialtyCode &&
    currentGroup.value.specialtyCode !== PROJECT_LEAD_GROUP_CODE
)

const buildSummaryCards = (group?: SpecialtyGroup) => {
  if (!group) {
    return []
  }
  return [
    { label: '分组金额', value: `${formatAmountText(group.specialtyAmount)} 元` },
    { label: '角色合计', value: formatPercentText(group.roleTotal) },
    { label: '已配置人数', value: `${group.personCount} 人` },
    { label: '超额提醒', value: group.roleTotal > 1 + EPSILON ? '存在' : '无' }
  ]
}

watch(
  groups,
  (value) => {
    const codes = value.map((item) => item.specialtyCode)
    if (!codes.length) {
      selectedGroupCode.value = ''
      return
    }
    const preferredCode = codes.find((code) => code !== PROJECT_LEAD_GROUP_CODE) || codes[0]
    if (!codes.includes(selectedGroupCode.value) || selectedGroupCode.value === PROJECT_LEAD_GROUP_CODE) {
      selectedGroupCode.value = preferredCode
    }
  },
  { immediate: true }
)

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
      roleList.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
    roleList.value = []
    return
  }
  planningLoading.value = true
  try {
    const list = await PlanningApi.getProjectPlanningListByProjectId(currentProject.value.id)
    planningList.value = list
    if (!planningList.value.length) {
      currentPlanning.value = undefined
      roleList.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 loadRoleList = async (planningId: number) => {
  roleList.value = await SpecialtyRoleSplitApi.getSpecialtyRoleSplitListByPlanningId(planningId)
}

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) {
    roleList.value = []
    return
  }
  await loadRoleList(row.id)
}

const handleExportSpecialtyPerson = async () => {
  if (!currentPlanning.value?.id) {
    message.warning('请先选择合约规划')
    return
  }
  if (!canExportCurrentGroup.value || !currentGroup.value?.specialtyCode) {
    message.warning('请选择具体专业后再导出')
    return
  }
  try {
    await message.exportConfirm()
    exportSpecialtyLoading.value = true
    const data = await ReportApi.exportSpecialtyPersonOutput({
      planningId: currentPlanning.value.id,
      specialtyCode: currentGroup.value.specialtyCode
    })
    download.excel(data, `${currentGroup.value.specialtyName || '专业'}内人员年度季度计取表.xlsx`)
  } finally {
    exportSpecialtyLoading.value = false
  }
}

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

onActivated(() => {
  getProjectList()
})
</script>

<style lang="scss" scoped>
.person-empty {
  font-size: 12px;
  color: var(--el-text-color-secondary);
}

.person-display-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.person-display-row {
  display: grid;
  grid-template-columns: minmax(120px, 1fr) 100px 120px;
  align-items: center;
  gap: 8px;
  font-size: 13px;
}

.person-display-name {
  font-weight: 600;
}
</style>
