<template>
  <Dialog v-model="dialogVisible" :title="dialogTitle" width="1080">
    <el-form
      ref="formRef"
      v-loading="formLoading"
      :model="formData"
      :rules="formRules"
      label-width="120px"
    >
      <el-row :gutter="16">
        <el-col :span="12">
          <el-form-item label="工程名称" prop="projectName">
            <el-input v-model="formData.projectName" maxlength="200" placeholder="请输入工程名称" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="是否签订合同" prop="contractSignedFlag">
            <el-switch
              v-model="formData.contractSignedFlag"
              active-text="已签订"
              inactive-text="未签订"
            />
          </el-form-item>
        </el-col>
      </el-row>

      <el-row :gutter="16">
        <el-col :span="12">
          <el-form-item label="合同金额(元)" prop="contractAmount">
            <el-input-number
              v-model="formData.contractAmount"
              :min="0"
              :precision="2"
              :step="1000"
              class="!w-1/1"
              controls-position="right"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="工程总面积(㎡)" prop="totalConstructionArea">
            <el-input-number
              v-model="formData.totalConstructionArea"
              :min="0"
              :precision="2"
              :step="100"
              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="constructionUnitName">
            <el-input
              v-model="formData.constructionUnitName"
              maxlength="200"
              placeholder="请输入建设单位"
            />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="工程类型" prop="projectType">
            <el-select v-model="formData.projectType" class="!w-1/1" clearable placeholder="请选择">
              <el-option
                v-for="item in PROJECT_TYPE_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="projectCategory">
            <el-select
              v-model="formData.projectCategory"
              class="!w-1/1"
              clearable
              placeholder="请选择"
            >
              <el-option
                v-for="item in PROJECT_CATEGORY_OPTIONS"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>

      <el-row :gutter="16">
        <el-col :span="12">
          <el-form-item label="联系人" prop="contactName">
            <el-input v-model="formData.contactName" maxlength="64" placeholder="请输入联系人" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="联系电话" prop="contactPhone">
            <el-input v-model="formData.contactPhone" maxlength="32" placeholder="请输入联系电话" />
          </el-form-item>
        </el-col>
      </el-row>

      <el-row :gutter="16">
        <el-col :span="12">
          <el-form-item label="合同签订日期" prop="contractSigningDate">
            <el-date-picker
              v-model="formData.contractSigningDate"
              class="!w-1/1"
              placeholder="请选择日期"
              type="date"
              value-format="YYYY-MM-DD"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="项目开始年度" prop="projectStartYear">
            <el-date-picker
              v-model="projectStartYearValue"
              class="!w-1/1"
              placeholder="请选择年度"
              type="year"
              value-format="YYYY"
            />
          </el-form-item>
        </el-col>
      </el-row>

      <el-row :gutter="16">
        <el-col :span="12">
          <el-form-item label="项目状态" prop="projectStatus">
            <el-select
              v-model="formData.projectStatus"
              class="!w-1/1"
              clearable
              placeholder="请选择项目状态"
            >
              <el-option
                v-for="item in PROJECT_STATUS_OPTIONS"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item :label="statusReasonLabel" :prop="statusReasonProp">
            <el-input
              v-if="formData.projectStatus === '暂停'"
              v-model="formData.pauseReason"
              maxlength="255"
              placeholder="请输入暂停原因"
            />
            <el-input
              v-else-if="formData.projectStatus === '中止'"
              v-model="formData.terminateReason"
              maxlength="255"
              placeholder="请输入中止原因"
            />
            <el-input v-else disabled placeholder="进行中或完成状态无需填写原因" />
          </el-form-item>
        </el-col>
      </el-row>

      <el-row :gutter="16">
        <el-col :span="12">
          <el-form-item label="项目经理">
            <div class="person-group">
              <div
                v-for="(item, index) in projectManagerPersons"
                :key="`manager-${index}`"
                class="person-row"
              >
                <el-select
                  :model-value="item.employeeId"
                  class="!w-1/1"
                  clearable
                  filterable
                  remote
                  reserve-keyword
                  placeholder="请输入项目经理姓名搜索"
                  :remote-method="searchEmployees"
                  :loading="employeeLoading"
                  @change="(value) => handleEmployeeChange(item, value)"
                >
                  <el-option
                    v-for="employee in employeeOptions"
                    :key="employee.id"
                    :label="employee.officeName ? `${employee.employeeName} / ${employee.officeName}` : employee.employeeName"
                    :value="employee.id"
                  />
                </el-select>
                <el-button text type="danger" @click="removeRolePerson(ROLE_PROJECT_MANAGER, index)">
                  删除
                </el-button>
              </div>
              <el-button text type="primary" @click="addRolePerson(ROLE_PROJECT_MANAGER)">
                <Icon class="mr-5px" icon="ep:plus" />
                添加项目经理
              </el-button>
            </div>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="项目负责人">
            <div class="person-group">
              <div
                v-for="(item, index) in engineeringPrincipalPersons"
                :key="`principal-${index}`"
                class="person-row"
              >
                <el-select
                  :model-value="item.employeeId"
                  class="!w-1/1"
                  clearable
                  filterable
                  remote
                  reserve-keyword
                  placeholder="请输入项目负责人姓名搜索"
                  :remote-method="searchEmployees"
                  :loading="employeeLoading"
                  @change="(value) => handleEmployeeChange(item, value)"
                >
                  <el-option
                    v-for="employee in employeeOptions"
                    :key="employee.id"
                    :label="employee.officeName ? `${employee.employeeName} / ${employee.officeName}` : employee.employeeName"
                    :value="employee.id"
                  />
                </el-select>
                <el-button
                  text
                  type="danger"
                  @click="removeRolePerson(ROLE_ENGINEERING_PRINCIPAL, index)"
                >
                  删除
                </el-button>
              </div>
              <el-button text type="primary" @click="addRolePerson(ROLE_ENGINEERING_PRINCIPAL)">
                <Icon class="mr-5px" icon="ep:plus" />
                添加项目负责人
              </el-button>
            </div>
          </el-form-item>
        </el-col>
      </el-row>
    </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 EmployeeApi from '@/api/tjt/employee'
import * as ProjectApi from '@/api/tjt/project'

defineOptions({ name: 'TjtProjectForm' })

const ROLE_PROJECT_MANAGER = 'project_manager'
const ROLE_ENGINEERING_PRINCIPAL = 'engineering_principal'

const PROJECT_TYPE_OPTIONS = [
  { label: '建筑工程', value: '建筑工程' },
  { label: '精装工程', value: '精装工程' },
  { label: '综合工程', value: '综合工程' },
  { label: '专项设计', value: '专项设计' },
  { label: 'BIM设计', value: 'BIM设计' },
  { label: '其他', value: '其他' }
]

const PROJECT_CATEGORY_OPTIONS = [
  { label: '住宅', value: '住宅' },
  { label: '公建', value: '公建' },
  { label: '工业', value: '工业' },
  { label: '园林景观', value: '园林景观' },
  { label: '其他', value: '其他' }
]

const PROJECT_STATUS_OPTIONS = [
  { label: '进行中', value: '进行中' },
  { label: '完成', value: '完成' },
  { label: '暂停', value: '暂停' },
  { label: '中止', value: '中止' }
]

const DEFAULT_INNOVATION_OUTPUT_RATE = 0.01

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

const dialogVisible = ref(false)
const dialogTitle = ref('')
const formLoading = ref(false)
const formType = ref<'create' | 'update'>('create')
const formRef = ref()
const employeeOptions = ref<EmployeeApi.EmployeeSimpleVO[]>([])
const employeeLoading = ref(false)

const createRolePerson = (
  roleCode: ProjectApi.ProjectRolePersonVO['roleCode']
): ProjectApi.ProjectRolePersonVO => ({
  roleCode,
  employeeId: undefined,
  employeeName: ''
})

const createFormData = (): ProjectApi.ProjectVO => ({
  projectName: '',
  contractSignedFlag: true,
  contractAmount: undefined,
  totalConstructionArea: undefined,
  constructionUnitName: '',
  contactName: '',
  contactPhone: '',
  contractSigningDate: undefined,
  projectType: '',
  projectCategory: '',
  projectStartYear: new Date().getFullYear(),
  projectStatus: '进行中',
  pauseReason: '',
  terminateReason: '',
  innovationOutputRate: DEFAULT_INNOVATION_OUTPUT_RATE,
  otherCost: 0,
  rolePersons: []
})

const formData = ref<ProjectApi.ProjectVO>(createFormData())

const normalizeValue = (value: string | undefined, options: Array<{ value: string }>, fallback = '') =>
  options.find((item) => item.value === value)?.value || fallback

const normalizeFormData = (data: ProjectApi.ProjectVO): ProjectApi.ProjectVO => ({
  ...createFormData(),
  ...data,
  projectType: normalizeValue(data.projectType, PROJECT_TYPE_OPTIONS),
  projectCategory: normalizeValue(data.projectCategory, PROJECT_CATEGORY_OPTIONS),
  projectStatus: normalizeValue(data.projectStatus, PROJECT_STATUS_OPTIONS, '进行中'),
  innovationOutputRate: data.innovationOutputRate ?? DEFAULT_INNOVATION_OUTPUT_RATE,
  otherCost: data.otherCost ?? 0,
  pauseReason: data.pauseReason || '',
  terminateReason: data.terminateReason || '',
  rolePersons: (data.rolePersons || []).map((item) => ({
    roleCode: item.roleCode,
    employeeId: item.employeeId,
    employeeName: item.employeeName,
    sortNo: item.sortNo
  }))
})

const getRolePersons = (roleCode: ProjectApi.ProjectRolePersonVO['roleCode']) => {
  if (!formData.value.rolePersons) {
    formData.value.rolePersons = []
  }
  return formData.value.rolePersons.filter((item) => item.roleCode === roleCode)
}

const projectManagerPersons = computed(() => getRolePersons(ROLE_PROJECT_MANAGER))
const engineeringPrincipalPersons = computed(() => getRolePersons(ROLE_ENGINEERING_PRINCIPAL))

const addRolePerson = (roleCode: ProjectApi.ProjectRolePersonVO['roleCode']) => {
  formData.value.rolePersons = [...(formData.value.rolePersons || []), createRolePerson(roleCode)]
}

const removeRolePerson = (roleCode: ProjectApi.ProjectRolePersonVO['roleCode'], index: number) => {
  const roleIndexes = (formData.value.rolePersons || [])
    .map((item, itemIndex) => ({ item, itemIndex }))
    .filter(({ item }) => item.roleCode === roleCode)
  const target = roleIndexes[index]
  if (!target) {
    return
  }
  formData.value.rolePersons?.splice(target.itemIndex, 1)
}

const ensureEmployeeOptions = (persons?: ProjectApi.ProjectRolePersonVO[]) => {
  const existingIds = new Set(employeeOptions.value.map((item) => item.id))
  ;(persons || []).forEach((item) => {
    if (!item.employeeId || existingIds.has(item.employeeId)) {
      return
    }
    employeeOptions.value.push({
      id: item.employeeId,
      employeeName: item.employeeName || '',
      officeId: undefined,
      officeName: undefined
    })
  })
}

const searchEmployees = async (keyword: string) => {
  employeeLoading.value = true
  try {
    employeeOptions.value = await EmployeeApi.getEmployeeSimpleList({
      keyword,
      enabledFlag: true
    })
    ensureEmployeeOptions(formData.value.rolePersons)
  } finally {
    employeeLoading.value = false
  }
}

const handleEmployeeChange = (item: ProjectApi.ProjectRolePersonVO, employeeId?: number) => {
  const employee = employeeOptions.value.find((option) => option.id === employeeId)
  item.employeeId = employeeId
  item.employeeName = employee?.employeeName || ''
}

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

const statusReasonLabel = computed(() =>
  formData.value.projectStatus === '中止' ? '中止原因' : '暂停原因'
)

const statusReasonProp = computed(() =>
  formData.value.projectStatus === '中止' ? 'terminateReason' : 'pauseReason'
)

watch(
  () => formData.value.projectStatus,
  (status) => {
    if (status !== '暂停') {
      formData.value.pauseReason = ''
    }
    if (status !== '中止') {
      formData.value.terminateReason = ''
    }
  }
)

const formRules = reactive<FormRules>({
  projectName: [{ required: true, message: '工程名称不能为空', trigger: 'blur' }],
  contractAmount: [{ required: true, message: '合同金额不能为空', trigger: 'blur' }],
  totalConstructionArea: [{ required: true, message: '工程总面积不能为空', trigger: 'blur' }],
  projectStartYear: [{ required: true, message: '项目开始年度不能为空', trigger: 'change' }],
  projectStatus: [{ required: true, message: '项目状态不能为空', trigger: 'change' }],
  pauseReason: [
    {
      validator: (_rule, value, callback) => {
        if (formData.value.projectStatus === '暂停' && !String(value || '').trim()) {
          callback(new Error('暂停状态必须填写暂停原因'))
          return
        }
        callback()
      },
      trigger: 'blur'
    }
  ],
  terminateReason: [
    {
      validator: (_rule, value, callback) => {
        if (formData.value.projectStatus === '中止' && !String(value || '').trim()) {
          callback(new Error('中止状态必须填写中止原因'))
          return
        }
        callback()
      },
      trigger: 'blur'
    }
  ]
})

const open = async (type: 'create' | 'update', id?: number) => {
  dialogVisible.value = true
  dialogTitle.value = type === 'create' ? '新增项目' : '编辑项目'
  formType.value = type
  resetForm()
  if (!id) {
    return
  }
  formLoading.value = true
  try {
    formData.value = normalizeFormData(await ProjectApi.getProject(id))
    ensureEmployeeOptions(formData.value.rolePersons)
  } finally {
    formLoading.value = false
  }
}
defineExpose({ open })

const emit = defineEmits(['success'])

const buildSavePayload = (): ProjectApi.ProjectSaveVO => ({
  id: formData.value.id,
  projectName: formData.value.projectName,
  contractSignedFlag: formData.value.contractSignedFlag,
  contractAmount: formData.value.contractAmount,
  totalConstructionArea: formData.value.totalConstructionArea,
  constructionUnitName: formData.value.constructionUnitName,
  contactName: formData.value.contactName,
  contactPhone: formData.value.contactPhone,
  contractSigningDate: formData.value.contractSigningDate,
  projectType: formData.value.projectType,
  projectCategory: formData.value.projectCategory,
  projectStartYear: formData.value.projectStartYear,
  projectStatus: formData.value.projectStatus,
  pauseReason: formData.value.pauseReason?.trim() || undefined,
  terminateReason: formData.value.terminateReason?.trim() || undefined,
  finalSettlementAmount: formData.value.finalSettlementAmount,
  innovationOutputRate: formData.value.innovationOutputRate,
  otherCost: formData.value.otherCost,
  rolePersons: (formData.value.rolePersons || [])
    .map((item, index) => ({
      roleCode: item.roleCode,
      employeeId: item.employeeId,
      employeeName: item.employeeName?.trim() || undefined,
      sortNo: index + 1
    }))
    .filter((item) => !!item.employeeId)
})

const submitForm = async () => {
  if (!formRef.value) {
    return
  }
  const valid = await formRef.value.validate()
  if (!valid) {
    return
  }
  formLoading.value = true
  try {
    const payload = buildSavePayload()
    if (formType.value === 'create') {
      await ProjectApi.createProject(payload)
      message.success(t('common.createSuccess'))
    } else {
      await ProjectApi.updateProject(payload)
      message.success(t('common.updateSuccess'))
    }
    dialogVisible.value = false
    emit('success')
  } finally {
    formLoading.value = false
  }
}

const resetForm = () => {
  formData.value = createFormData()
  employeeOptions.value = []
  formRef.value?.resetFields()
}
</script>

<style lang="scss" scoped>
.person-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
}

.person-row {
  display: grid;
  gap: 8px;
  grid-template-columns: minmax(0, 1fr) 56px;
}
</style>
