<template>
  <el-drawer v-model="visible" :title="mode === 'edit' ? '编辑项目' : '新建项目'" size="65%">
    <el-form ref="formRef" :model="projectForm" label-position="left" :label-width="LABEL_WIDTH.lg" :rules="formRules">
      <el-form-item label="项目名称" prop="name">
        <el-input v-model="projectForm.name" />
      </el-form-item>
      <el-form-item label="上级项目ID">
        <el-input :model-value="projectForm.parentProjectId || ''" disabled placeholder="一级项目" />
      </el-form-item>
      <el-form-item label="项目周期">
        <el-date-picker
          v-model="projectDateRange"
          type="daterange"
          value-format="YYYY-MM-DD"
          range-separator="~"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
        />
      </el-form-item>
      <el-form-item label="合作企业" prop="partnerEnterpriseId">
        <el-select v-model="projectForm.partnerEnterpriseId" clearable class="w-full">
          <el-option v-for="e in enterprises" :key="e.id" :label="e.enterpriseName" :value="e.id" />
        </el-select>
      </el-form-item>
      <el-form-item label="主办单位">
        <el-input v-model="projectForm.hostEnterpriseName" disabled />
      </el-form-item>
      <el-form-item label="预算（元）">
        <el-input-number v-model="budgetYuan" :min="1" :step="1" :precision="2" class="project-number-input" />
      </el-form-item>
      <el-form-item label="会议期数">
        <el-input-number v-model="projectForm.meetingTotal" :min="1" class="project-number-input" />
      </el-form-item>
      <el-form-item label="管理费">
        <el-input-number v-model="managementFeeYuan" :min="0" :step="1" :precision="2" class="project-number-input" />
      </el-form-item>
      <el-form-item label="税费（元）">
        <el-input-number v-model="taxFeeYuan" :min="0" :step="1" :precision="2" class="project-number-input" />
      </el-form-item>
      <el-form-item label="到款金额（元）">
        <el-input-number v-model="paidAmountYuan" :min="0" :step="1" :precision="2" class="project-number-input" />
      </el-form-item>
      <el-form-item label="自定义费用">
        <div class="w-full">
          <div
            v-for="(fee, idx) in projectForm.customFees"
            :key="idx"
            style="display: flex; gap: 8px; align-items: center; margin-bottom: 8px"
          >
            <el-input v-model="fee.name" placeholder="费用名称" />
            <el-input-number
              :model-value="getCustomFeeYuan(idx)"
              :min="0"
              :step="1"
              :precision="2"
              style="width: 280px;"
              @update:model-value="setCustomFeeYuan(idx, $event)"
            />
            <el-button type="danger" plain @click="projectForm.customFees.splice(idx, 1)">删除</el-button>
          </div>
          <el-button type="primary" plain @click="projectForm.customFees.push({ name: '', amountCent: 0, remark: '' })">
            新增费用
          </el-button>
        </div>
      </el-form-item>

      <el-form-item label="劳务费用占比">
        <el-input-number v-model="projectForm.laborFeeRatio" :min="0" :max="1" :step="0.01" class="project-number-input" />
      </el-form-item>
      <el-form-item label="允许单场超支">
        <el-switch v-model="projectForm.allowMeetingOverBudget" />
      </el-form-item>
      <el-form-item label="允许项目超支">
        <el-switch v-model="projectForm.allowProjectOverBudget" />
      </el-form-item>
      <el-form-item label="超支阈值">
        <el-input-number v-model="projectForm.overBudgetThresholdRatio" :min="0" :max="1" :step="0.01" class="project-number-input" />
      </el-form-item>
      <el-form-item label="发票信息">
        <el-input v-model="projectForm.invoiceInfo" />
      </el-form-item>
      <el-form-item label="主办单位负责人">
        <el-input :model-value="projectForm.hostOwnerUsers || '系统自动取TENANT_ADMIN'" disabled />
      </el-form-item>
      <el-form-item label="主办单位项目执行人">
        <el-input :model-value="projectForm.hostExecutorUsers || '系统自动取PROJECT_OWNER绑定人员'" disabled />
      </el-form-item>
      <el-form-item label="合作企业负责人">
        <el-input :model-value="projectForm.partnerOwnerUsers || '系统自动取PROJECT_EXECUTOR绑定人员'" disabled />
      </el-form-item>
      <el-form-item label="合作企业项目执行人">
        <el-input :model-value="projectForm.partnerExecutorUsers || '系统自动取EXECUTOR绑定人员'" disabled />
      </el-form-item>
      <el-form-item label="说明">
        <el-input model-value="人员角色由项目绑定表自动维护" disabled />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="visible = false">取消</el-button>
      <el-button type="primary" @click="handleSubmit">保存</el-button>
    </template>
  </el-drawer>
</template>

<script setup lang="ts">
import { computed, ref, watch } from "vue";
import { ElMessage } from "element-plus";
import type { FormInstance, FormRules } from "element-plus";
import { createProject, fetchEnterprises, updateProject } from "../../../api/modules";
import { LABEL_WIDTH } from "../../../constants/ui";
import { useAuthStore } from "../../../stores/auth";

const props = defineProps<{
  modelValue: boolean;
  mode: "create" | "edit";
  sourceRow?: any | null;
  editId?: number | null;
}>();

const emit = defineEmits<{
  "update:modelValue": [value: boolean];
  saved: [];
}>();
const authStore = useAuthStore();

const visible = computed({
  get: () => props.modelValue,
  set: (value: boolean) => emit("update:modelValue", value),
});

const defaultForm = () => ({
  name: "",
  parentProjectId: undefined as number | undefined,
  partnerEnterpriseId: undefined as number | undefined,
  hostEnterpriseName: authStore.tenantName || "",
  budgetCent: 1000000,
  meetingTotal: 1,
  paymentStatus: "WAIT_SUBMIT",
  writeOffStatus: "WAITING",
  laborFeeRatio: 0,
  allowMeetingOverBudget: false,
  allowProjectOverBudget: false,
  overBudgetThresholdRatio: 0.1,
  invoiceInfo: "",
  hostOwnerUsers: "",
  hostExecutorUsers: "",
  partnerOwnerUsers: "",
  partnerExecutorUsers: "",
  managementFeeCent: 0,
  taxFeeCent: 0,
  paidAmountCent: 0,
  customFees: [] as Array<{ name: string; amountCent: number; remark?: string }>,
});

const enterprises = ref<any[]>([]);
const enterpriseLoaded = ref(false);
const enterpriseLoading = ref(false);
const projectDateRange = ref<string[]>([]);
const projectForm = ref(defaultForm());

const formRef = ref<FormInstance>();
const formRules = ref<FormRules>({
  name: [{ required: true, message: "请输入项目名称", trigger: "blur" }],
  partnerEnterpriseId: [{ required: true, message: "请选择合作企业", trigger: "change" }],
});

const toYuan = (cent: unknown) => Number(((Number(cent) || 0) / 100).toFixed(2));
const toCent = (yuan: unknown) => Math.round((Number(yuan) || 0) * 100);

const budgetYuan = computed({
  get: () => toYuan(projectForm.value.budgetCent),
  set: (value: number) => {
    projectForm.value.budgetCent = toCent(value);
  },
});
const managementFeeYuan = computed({
  get: () => toYuan(projectForm.value.managementFeeCent),
  set: (value: number) => {
    projectForm.value.managementFeeCent = toCent(value);
  },
});
const taxFeeYuan = computed({
  get: () => toYuan(projectForm.value.taxFeeCent),
  set: (value: number) => {
    projectForm.value.taxFeeCent = toCent(value);
  },
});
const paidAmountYuan = computed({
  get: () => toYuan(projectForm.value.paidAmountCent),
  set: (value: number) => {
    projectForm.value.paidAmountCent = toCent(value);
  },
});
const getCustomFeeYuan = (idx: number) => toYuan(projectForm.value.customFees?.[idx]?.amountCent);
const setCustomFeeYuan = (idx: number, value: number | null | undefined) => {
  if (!projectForm.value.customFees?.[idx]) return;
  projectForm.value.customFees[idx].amountCent = toCent(value);
};

const parseProjectFee = (projectFeeJson: unknown) => {
  const defaults = {
    managementFeeCent: 0,
    taxFeeCent: 0,
    paidAmountCent: 0,
    customFees: [] as Array<{ name: string; amountCent: number; remark?: string }>,
  };
  if (!projectFeeJson) return defaults;
  try {
    const parsed = JSON.parse(String(projectFeeJson));
    return {
      managementFeeCent: Math.max(0, Number(parsed?.managementFeeCent) || 0),
      taxFeeCent: Math.max(0, Number(parsed?.taxFeeCent) || 0),
      paidAmountCent: Math.max(0, Number(parsed?.paidAmountCent) || 0),
      customFees: Array.isArray(parsed?.customFees)
        ? parsed.customFees
            .map((item: any) => ({
              name: String(item?.name || "").trim(),
              amountCent: Math.max(0, Number(item?.amountCent) || 0),
              remark: String(item?.remark || ""),
            }))
            .filter((item: { name: string }) => !!item.name)
        : [],
    };
  } catch (_e) {
    return defaults;
  }
};

const buildProjectFeeJson = () =>
  JSON.stringify({
    managementFeeCent: Math.max(0, Number(projectForm.value.managementFeeCent) || 0),
    taxFeeCent: Math.max(0, Number(projectForm.value.taxFeeCent) || 0),
    paidAmountCent: Math.max(0, Number(projectForm.value.paidAmountCent) || 0),
    customFees: (projectForm.value.customFees || [])
      .map((item: { name: string; amountCent: number; remark?: string }) => ({
        name: String(item.name || "").trim(),
        amountCent: Math.max(0, Number(item.amountCent) || 0),
        remark: String(item.remark || ""),
      }))
      .filter((item: { name: string }) => !!item.name),
  });

const validateCustomFees = () => {
  const invalidItem = (projectForm.value.customFees || []).find((item: { name: string; amountCent: number }) => {
    const hasName = !!String(item.name || "").trim();
    const amount = Number(item.amountCent) || 0;
    return !hasName || amount < 0;
  });
  if (!invalidItem) return true;
  ElMessage.warning("自定义费用需填写名称，且金额不能为负");
  return false;
};

const buildPayload = () => ({
  name: projectForm.value.name,
  parentProjectId: projectForm.value.parentProjectId,
  startDate: projectDateRange.value?.[0] || undefined,
  endDate: projectDateRange.value?.[1] || undefined,
  partnerEnterpriseId: projectForm.value.partnerEnterpriseId,
  budgetCent: projectForm.value.budgetCent,
  meetingTotal: projectForm.value.meetingTotal,
  allowMeetingOverBudget: projectForm.value.allowMeetingOverBudget,
  overBudgetThresholdRatio: projectForm.value.overBudgetThresholdRatio,
  overBudgetApprovalChainJson: JSON.stringify(["EXECUTOR", "OWNER", "FINANCE"]),
  paymentStatus: projectForm.value.paymentStatus,
  writeOffStatus: projectForm.value.writeOffStatus,
  laborFeeRatio: projectForm.value.laborFeeRatio,
  allowProjectOverBudget: projectForm.value.allowProjectOverBudget,
  invoiceInfo: projectForm.value.invoiceInfo,
  expenseRatioJson: JSON.stringify({ labor: projectForm.value.laborFeeRatio }),
  projectFeeJson: buildProjectFeeJson(),
});

const resetForCreate = (parentRow?: any | null) => {
  projectForm.value = defaultForm();
  if (parentRow?.id) {
    projectForm.value.parentProjectId = parentRow.id;
    projectForm.value.partnerEnterpriseId = parentRow.partnerEnterpriseId ?? parentRow.enterpriseId;
    projectForm.value.budgetCent = parentRow.budgetCent;
    projectForm.value.meetingTotal = parentRow.meetingTotal;
    const parentProjectFee = parseProjectFee(parentRow.projectFeeJson);
    projectForm.value.managementFeeCent = parentProjectFee.managementFeeCent;
    projectForm.value.taxFeeCent = parentProjectFee.taxFeeCent;
    projectForm.value.paidAmountCent = parentProjectFee.paidAmountCent;
    projectForm.value.customFees = parentProjectFee.customFees;
  }
  projectDateRange.value = [];
};

const resetForEdit = (row: any) => {
  projectForm.value = {
    ...defaultForm(),
    ...row,
  };
  const projectFee = parseProjectFee(row?.projectFeeJson);
  projectForm.value.managementFeeCent = projectFee.managementFeeCent;
  projectForm.value.taxFeeCent = projectFee.taxFeeCent;
  projectForm.value.paidAmountCent = projectFee.paidAmountCent;
  projectForm.value.customFees = projectFee.customFees;
  projectDateRange.value = [row?.startDate, row?.endDate].filter(Boolean);
};

const ensureEnterprises = async () => {
  if (enterpriseLoaded.value || enterpriseLoading.value) return;
  enterpriseLoading.value = true;
  try {
    const enterpriseResp = await fetchEnterprises();
    enterprises.value = enterpriseResp?.data?.list || [];
    enterpriseLoaded.value = true;
  } catch (_e) {
    enterprises.value = [];
  } finally {
    enterpriseLoading.value = false;
  }
};

watch(
  () => [props.modelValue, props.mode, props.sourceRow, props.editId],
  async () => {
    if (!props.modelValue) return;
    await ensureEnterprises();
    if (props.mode === "edit") {
      resetForEdit(props.sourceRow || {});
      return;
    }
    resetForCreate(props.sourceRow || null);
  },
  { immediate: true },
);

const handleSubmit = async () => {
  if (!formRef.value) return;
  const valid = await formRef.value.validate().catch(() => false);
  if (!valid) return;

  if (!validateCustomFees()) return;
  if (props.mode === "edit") {
    if (!props.editId) return;
    await updateProject(props.editId, buildPayload());
    ElMessage.success("项目更新成功");
  } else {
    await createProject(buildPayload());
    ElMessage.success("项目创建成功");
  }
  visible.value = false;
  emit("saved");
};
</script>

<style scoped>
.project-number-input {
  width: 180px;
}
</style>
