<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 flex items-center justify-between">
          <div class="text-14px font-600">
            {{ currentProject?.projectName || '专业所规划列表' }}
          </div>
          <el-button v-if="currentProject" size="small" @click="getPlanningList">刷新</el-button>
        </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="开始年度" 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 && currentSpecialtyGroup">
        <div class="mb-16px flex items-center justify-between gap-12px">
          <div>
            <div class="text-16px font-600">{{ currentPlanning.planningContent }}</div>
          </div>
          <div class="flex items-center gap-12px">
            <el-button
              v-hasPermi="['tjt:specialty-role-split:update']"
              plain
              type="primary"
              @click="openEditDialog"
            >
              <Icon class="mr-5px" icon="ep:edit" />
              编辑人员分配
            </el-button>
            <el-button @click="refreshCurrentPlanning">
              <Icon class="mr-5px" icon="ep:refresh" />
              刷新结果
            </el-button>
          </div>
        </div>

        <div class="mb-16px flex flex-wrap items-start justify-between gap-12px">
          <el-radio-group v-model="selectedSpecialtyCode" size="small">
            <el-radio-button
              v-for="item in specialtyTabOptions"
              :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 currentSpecialtySummaryCards" :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="currentSpecialtyGroup.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.personName || '-' }}</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="请选择专业所规划后查看页面5结果" />
      </ContentWrap>
    </el-col>
  </el-row>

  <Dialog v-model="dialogVisible" title="编辑专业人员角色分配" width="1180">
    <template v-if="currentEditSpecialtyGroup">

      <div class="mb-16px flex flex-wrap items-start justify-between gap-12px">
        <el-radio-group v-model="editSpecialtyCode" size="small">
          <el-radio-button
            v-for="item in specialtyTabOptions"
            :key="`edit-${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 currentEditSpecialtySummaryCards" :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="currentEditSpecialtyGroup.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">
            <el-input-number
              :model-value="toPercentValue(scope.row.roleRatio)"
              :max="100"
              :min="0"
              :precision="2"
              :step="0.1"
              class="!w-1/1"
              controls-position="right"
              @update:model-value="(value) => updateRoleRatio(scope.row, value)"
            />
          </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">
            <span :class="getPersonTotalClass(scope.row)">
              {{ formatPercentText(getPersonTotalRatio(scope.row)) }}
            </span>
          </template>
        </el-table-column>
        <el-table-column label="人员配置" min-width="520">
          <template #default="scope">
            <div class="person-editor">
              <div v-if="!scope.row.persons?.length" class="person-empty">
                暂无人员，请点击“添加人员”
              </div>
              <div
                v-for="(person, index) in scope.row.persons"
                :key="`${scope.row.specialtyCode}-${scope.row.roleCode}-${index}`"
                class="person-row"
              >
                <el-input
                  v-model="person.personName"
                  clearable
                  maxlength="64"
                  placeholder="请输入人员名称"
                />
                <el-input-number
                  :model-value="toPercentValue(person.personRatio)"
                  :max="getPersonRatioMax(scope.row, person)"
                  :min="0"
                  :precision="2"
                  :step="0.1"
                  class="!w-1/1"
                  controls-position="right"
                  placeholder="比例(%)"
                  @update:model-value="(value) => updatePersonRatio(scope.row, person, value)"
                />
                <div class="person-amount">{{ formatAmountText(person.personAmount) }} 元</div>
                <el-button text type="danger" @click="removePerson(scope.row, index)">
                  删除
                </el-button>
              </div>
              <div class="person-toolbar">
                <el-button text type="primary" @click="addPerson(scope.row)">
                  <Icon class="mr-5px" icon="ep:plus" />
                  添加人员
                </el-button>
              </div>
            </div>
          </template>
        </el-table-column>
      </el-table>
    </template>
    <template #footer>
      <el-button :loading="saveLoading" type="primary" @click="handleSave">保存</el-button>
      <el-button @click="dialogVisible = false">取消</el-button>
    </template>
  </Dialog>
</template>

<script lang="ts" setup>
import * as ProjectApi from '@/api/tjt/project'
import * as PlanningApi from '@/api/tjt/planning'
import * as SpecialtyRoleSplitApi from '@/api/tjt/specialtyRoleSplit'
import {
  formatAmountText,
  formatPercentText,
  fromPercentValue,
  isMajorOwnership,
  OUTPUT_SPLIT_SPECIALTY_OPTIONS,
  toPercentValue
} from '@/views/tjt/shared/planning'

defineOptions({ name: 'TjtStaffAssignment' })

const DESIGN_ROLE_CODE = 'design'
const EPSILON = 0.0001

type SpecialtyRolePersonVO = SpecialtyRoleSplitApi.SpecialtyRolePersonVO
type SpecialtyRoleSplitVO = SpecialtyRoleSplitApi.SpecialtyRoleSplitVO

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

const message = useMessage()

const loading = ref(false)
const planningLoading = ref(false)
const saveLoading = 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 editRoleList = ref<SpecialtyRoleSplitVO[]>([])
const selectedSpecialtyCode = ref('')
const editSpecialtyCode = ref('')
const dialogVisible = ref(false)
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)
  if (Number.isNaN(numericValue)) {
    return 0
  }
  return Number(numericValue.toFixed(4))
}

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

const multiplyAmount = (amount?: number | string | null, ratio?: number | string | null) => {
  return roundAmount(Number(amount || 0) * Number(ratio || 0))
}

const normalizePersonName = (value?: string) => value?.trim() || ''

const buildEditablePerson = (person?: SpecialtyRolePersonVO): SpecialtyRolePersonVO => ({
  personName: person?.personName || '',
  personRatio:
    person?.personRatio === undefined || person?.personRatio === null
      ? undefined
      : roundRatio(person.personRatio),
  personAmount: roundAmount(person?.personAmount)
})

const buildEditableRow = (row: SpecialtyRoleSplitVO): SpecialtyRoleSplitVO => ({
  ...row,
  specialtyAmount: roundAmount(row.specialtyAmount),
  roleRatio: roundRatio(row.roleRatio),
  roleAmount: roundAmount(row.roleAmount),
  persons: (row.persons || []).map((person) => buildEditablePerson(person))
})

const cloneRoleRows = (rows: SpecialtyRoleSplitVO[]) => rows.map((item) => buildEditableRow(item))

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

const getPersonTotalRatio = (row: SpecialtyRoleSplitVO) => sumPersonRatios(row.persons)

const getPersonTotalClass = (row: SpecialtyRoleSplitVO) =>
  getPersonTotalRatio(row) > 1 + EPSILON ? 'text-[var(--el-color-danger)]' : ''

const getPersonRatioMax = (row: SpecialtyRoleSplitVO, currentPerson: SpecialtyRolePersonVO) => {
  const otherTotalRatio = roundRatio(
    (row.persons || []).reduce((sum, person) => {
      if (person === currentPerson) {
        return sum
      }
      return sum + Number(person?.personRatio || 0)
    }, 0)
  )
  const currentPercent = toPercentValue(currentPerson.personRatio) ?? 0
  const remainPercent = toPercentValue(Math.max(0, 1 - otherTotalRatio)) ?? 0
  return Math.min(100, Math.max(currentPercent, remainPercent))
}

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

const syncSpecialtyRows = (source: SpecialtyRoleSplitVO[], specialtyCode: string) => {
  const rows = source.filter((item) => item.specialtyCode === specialtyCode)
  rows.forEach((row) => {
    row.persons = (row.persons || []).map((person) => buildEditablePerson(person))
    row.roleRatio = roundRatio(row.roleRatio)
    row.roleAmount = multiplyAmount(row.specialtyAmount, row.roleRatio)
    row.persons = (row.persons || []).map((person) => ({
      ...person,
      personAmount: multiplyAmount(row.roleAmount, person.personRatio)
    }))
  })
}

const syncAllDerivedValues = (source: SpecialtyRoleSplitVO[]) => {
  const specialtyCodeSet = new Set(source.map((item) => item.specialtyCode))
  specialtyCodeSet.forEach((specialtyCode) => syncSpecialtyRows(source, specialtyCode))
}

const buildSpecialtyGroups = (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 OUTPUT_SPLIT_SPECIALTY_OPTIONS.map((option) => {
    const rows = map.get(option.value)
    if (!rows?.length) {
      return undefined
    }
    const sortedRows = [...rows].sort((a, b) => Number(a.sortNo || 0) - Number(b.sortNo || 0))
    const specialtyName = sortedRows[0]?.specialtyName || option.label
    const specialtyAmount = roundAmount(sortedRows[0]?.specialtyAmount)
    const roleTotal = roundRatio(
      sortedRows.reduce((sum, item) => sum + Number(item.roleRatio || 0), 0)
    )
    const designRow = sortedRows.find((item) => item.roleCode === DESIGN_ROLE_CODE)
    const personCount = sortedRows.reduce(
      (sum, row) => sum + countConfiguredPersons(row.persons),
      0
    )
    return {
      specialtyCode: option.value,
      specialtyName,
      specialtyAmount,
      rows: sortedRows,
      roleTotal,
      designRatio: roundRatio(designRow?.roleRatio),
      personCount
    }
  }).filter((item): item is SpecialtyGroup => !!item)
}

const specialtyGroups = computed(() => buildSpecialtyGroups(roleList.value))
const editSpecialtyGroups = computed(() => buildSpecialtyGroups(editRoleList.value))
const specialtyTabOptions = computed(() =>
  specialtyGroups.value.map((item) => ({
    label: item.specialtyName,
    value: item.specialtyCode
  }))
)

const currentSpecialtyGroup = computed(
  () =>
    specialtyGroups.value.find((item) => item.specialtyCode === selectedSpecialtyCode.value) ||
    specialtyGroups.value[0]
)

const currentEditSpecialtyGroup = computed(
  () =>
    editSpecialtyGroups.value.find((item) => item.specialtyCode === editSpecialtyCode.value) ||
    editSpecialtyGroups.value[0]
)

const buildSpecialtySummaryCards = (group?: SpecialtyGroup) => {
  if (!group) {
    return []
  }
  return [
    { label: '专业金额', value: `${formatAmountText(group.specialtyAmount)} 元` },
    { label: '角色合计', value: formatPercentText(group.roleTotal) },
    { label: '设计比例', value: formatPercentText(group.designRatio) },
    { label: '已配置人数', value: `${group.personCount} 人` }
  ]
}

const currentSpecialtySummaryCards = computed(() =>
  buildSpecialtySummaryCards(currentSpecialtyGroup.value)
)
const currentEditSpecialtySummaryCards = computed(() =>
  buildSpecialtySummaryCards(currentEditSpecialtyGroup.value)
)

const ensureSelectedCode = (codes: string[], target: { value: string }) => {
  if (!codes.length) {
    target.value = ''
    return
  }
  if (!codes.includes(target.value)) {
    target.value = codes[0]
  }
}

watch(
  specialtyGroups,
  (groups) => {
    ensureSelectedCode(
      groups.map((item) => item.specialtyCode),
      selectedSpecialtyCode
    )
  },
  { immediate: true }
)

watch(
  editSpecialtyGroups,
  (groups) => {
    ensureSelectedCode(
      groups.map((item) => item.specialtyCode),
      editSpecialtyCode
    )
  },
  { immediate: true }
)

const addPerson = (row: SpecialtyRoleSplitVO) => {
  if (!row.persons) {
    row.persons = []
  }
  row.persons.push(buildEditablePerson())
  syncSpecialtyRows(editRoleList.value, row.specialtyCode)
}

const removePerson = (row: SpecialtyRoleSplitVO, index: number) => {
  row.persons?.splice(index, 1)
  syncSpecialtyRows(editRoleList.value, row.specialtyCode)
}

const updatePersonRatio = (
  row: SpecialtyRoleSplitVO,
  person: SpecialtyRolePersonVO,
  value?: number
) => {
  const maxValue = getPersonRatioMax(row, person)
  const nextValue =
    value === undefined || value === null ? undefined : Math.min(Math.max(value, 0), maxValue)
  person.personRatio = fromPercentValue(nextValue) ?? undefined
  syncSpecialtyRows(editRoleList.value, row.specialtyCode)
}

const updateRoleRatio = (row: SpecialtyRoleSplitVO, value?: number) => {
  row.roleRatio = fromPercentValue(value) ?? 0
  syncSpecialtyRows(editRoleList.value, row.specialtyCode)
}

const buildSavePersons = (
  row: SpecialtyRoleSplitVO
):
  | { persons: SpecialtyRolePersonVO[]; error?: never }
  | { persons?: never; error: string } => {
  const persons: SpecialtyRolePersonVO[] = []
  for (const person of row.persons || []) {
    const personName = normalizePersonName(person.personName)
    const hasName = !!personName
    const hasRatio = person.personRatio !== undefined && person.personRatio !== null
    if (!hasName && !hasRatio) {
      continue
    }
    if (!hasName || !hasRatio) {
      return {
        error: `${row.specialtyName || row.specialtyCode}-${row.roleName || row.roleCode}的人员名称和比例必须同时填写`
      }
    }
    persons.push({
      personName,
      personRatio: roundRatio(person.personRatio)
    })
  }
  return { persons }
}

const validateAndBuildSaveItems = () => {
  const items: SpecialtyRoleSplitApi.SpecialtyRoleSplitSaveItemVO[] = []
  for (const group of editSpecialtyGroups.value) {
    let roleTotal = 0
    for (const row of group.rows) {
      const result = buildSavePersons(row)
      if (result.error) {
        message.warning(result.error)
        return undefined
      }
      const persons = result.persons || []
      const personTotalRatio = sumPersonRatios(persons)
      if (personTotalRatio > 1 + EPSILON) {
        message.warning(
          `${row.specialtyName || row.specialtyCode}-${row.roleName || row.roleCode}的人员比例合计不能大于 100%`
        )
        return undefined
      }
      if ((row.roleCode === DESIGN_ROLE_CODE && Number(row.roleAmount || 0) > EPSILON) && persons.length === 0) {
        message.warning(`${group.specialtyName}的设计角色金额大于 0 时必须至少配置 1 个人员`)
        return undefined
      }
      roleTotal = roundRatio(roleTotal + Number(row.roleRatio || 0))
      items.push({
        specialtyCode: row.specialtyCode,
        roleCode: row.roleCode,
        roleRatio: roundRatio(row.roleRatio),
        persons
      })
    }
    if (Math.abs(roleTotal - 1) > EPSILON) {
      message.warning(`${group.specialtyName}五类角色比例合计必须等于 100%`)
      return undefined
    }
  }
  return items
}

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 = []
      editRoleList.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 = []
    editRoleList.value = []
    return
  }
  planningLoading.value = true
  try {
    const list = await PlanningApi.getProjectPlanningListByProjectId(currentProject.value.id)
    planningList.value = list.filter((item) => isMajorOwnership(item.ownershipType))
    if (!planningList.value.length) {
      currentPlanning.value = undefined
      roleList.value = []
      editRoleList.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) => {
  const data = await SpecialtyRoleSplitApi.getSpecialtyRoleSplitListByPlanningId(planningId)
  roleList.value = cloneRoleRows(data)
  syncAllDerivedValues(roleList.value)
}

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

const refreshCurrentPlanning = async () => {
  if (!currentPlanning.value?.id) {
    return
  }
  await loadRoleList(currentPlanning.value.id)
}

const openEditDialog = () => {
  if (!roleList.value.length) {
    return
  }
  editRoleList.value = cloneRoleRows(roleList.value)
  syncAllDerivedValues(editRoleList.value)
  editSpecialtyCode.value = selectedSpecialtyCode.value || specialtyTabOptions.value[0]?.value || ''
  dialogVisible.value = true
}

const handleSave = async () => {
  if (!currentPlanning.value?.id) {
    return
  }
  const items = validateAndBuildSaveItems()
  if (!items) {
    return
  }
  saveLoading.value = true
  try {
    await SpecialtyRoleSplitApi.saveSpecialtyRoleSplitBatch({
      planningId: currentPlanning.value.id,
      items
    })
    message.success('保存成功')
    dialogVisible.value = false
    await loadRoleList(currentPlanning.value.id)
  } finally {
    saveLoading.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,
.person-editor {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.person-display-row,
.person-row {
  display: grid;
  align-items: center;
  gap: 8px;
}

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

.person-display-name {
  font-weight: 600;
}

.person-row {
  grid-template-columns: minmax(160px, 1fr) 180px 120px 64px;
}

.person-amount {
  color: var(--el-text-color-regular);
  text-align: right;
  white-space: nowrap;
}

.person-toolbar {
  display: flex;
  justify-content: flex-start;
}

@media (max-width: 1500px) {
  .person-row {
    grid-template-columns: minmax(140px, 1fr) 160px 110px 64px;
  }
}
</style>
