<template>
  <el-drawer
    v-if="modelValue"
    :model-value="modelValue"
    direction="rtl"
    size="720px"
    :close-on-click-modal="true"
    :before-close="drawerDirtyGuard.beforeClose"
    :show-close="false"
    class="contract-fee-editor-drawer"
    @update:model-value="emit('update:modelValue', $event)"
  >
    <template #header>
      <div class="editor-header">
        <div class="editor-title">{{ contractId ? TEXT.modules.feeContracts.editTitle : TEXT.modules.feeContracts.newTitle }}</div>
      </div>
    </template>

    <StateError v-if="drawerErrorMessage" :description="drawerErrorMessage">
      <template #action>
        <el-button type="primary" @click="reloadEditingDetail">{{ TEXT.common.actions.retry }}</el-button>
      </template>
    </StateError>

    <StateLoading v-else-if="drawerLoading" :rows="6" />

    <el-form v-else ref="formRef" :model="form" :rules="rules" label-position="top" class="contract-fee-form">
      <!-- 合同信息 -->
      <div class="form-section">
        <div class="form-section-title">
          <span class="dot dot--blue" />
          {{ TEXT.modules.feeContracts.contractInfoTitle }}
        </div>

        <div class="field-grid field-grid--3">
          <el-form-item :label="TEXT.common.fields.site" prop="center_id">
            <el-select
              v-model="form.center_id"
              :disabled="!!contractId || isFormReadOnly"
              :placeholder="TEXT.common.placeholders.select"
              class="full-width"
            >
              <el-option
                v-for="site in sites"
                :key="site.id"
                :label="site.name || TEXT.common.fallback"
                :value="site.id"
                :disabled="!site.is_active"
              />
            </el-select>
          </el-form-item>
          <el-form-item :label="TEXT.common.fields.contractNo" prop="contract_no">
            <el-input v-model="form.contract_no" :disabled="isFormReadOnly" :placeholder="TEXT.common.placeholders.input" />
          </el-form-item>
          <el-form-item :label="TEXT.common.fields.signedDate" prop="signed_date">
            <el-date-picker
              v-model="form.signed_date"
              :disabled="isFormReadOnly"
              type="date"
              value-format="YYYY-MM-DD"
              :placeholder="TEXT.common.placeholders.select"
              class="full-width"
            />
          </el-form-item>
        </div>

        <div class="field-grid field-grid--3">
          <el-form-item :label="`${TEXT.modules.feeContracts.contractAmount}（万元）`" prop="contract_amount">
            <el-input-number
              v-model="form.contract_amount"
              :disabled="isFormReadOnly"
              :min="0"
              :precision="2"
              :step="1"
              class="full-width"
              controls-position="right"
            />
          </el-form-item>
          <el-form-item :label="TEXT.modules.feeContracts.contractCases" prop="contract_cases">
            <el-input-number v-model="form.contract_cases" :disabled="isFormReadOnly" :min="0" :step="1" class="full-width" controls-position="right" />
          </el-form-item>
          <el-form-item :label="TEXT.modules.feeContracts.actualCases" prop="actual_cases">
            <el-input-number v-model="form.actual_cases" :disabled="isFormReadOnly" :min="0" :step="1" class="full-width" controls-position="right" />
          </el-form-item>
        </div>

        <el-form-item :label="TEXT.common.fields.remark" prop="remark">
          <el-input v-model="form.remark" :disabled="isFormReadOnly" type="textarea" :rows="3" :placeholder="TEXT.common.placeholders.input" />
        </el-form-item>

        <div v-if="selectedSiteInactive" class="inactive-hint">
          <span class="hint-icon">!</span>
          <span>中心已停用，当前记录不可编辑</span>
        </div>
      </div>

      <!-- 分期付款 -->
      <div class="form-section">
        <div class="form-section-title form-section-title--action">
          <span class="section-title-left">
            <span class="dot dot--amber" />
            {{ TEXT.modules.feeContracts.paymentTitle }}
          </span>
          <el-button type="primary" size="small" :disabled="isFormReadOnly" @click="addPayment" class="add-payment-btn">
            <el-icon class="el-icon--left"><Plus /></el-icon>
            {{ TEXT.common.actions.add }}
          </el-button>
        </div>

        <div v-if="payments.length === 0" class="section-empty">
          {{ TEXT.modules.feeContracts.paymentEmpty }}
        </div>

        <div v-else class="payment-list">
          <div v-for="(payment, index) in payments" :key="payment.tempId" class="payment-card">
            <div class="payment-card-header">
              <div class="payment-card-seq">
                <span class="seq-badge">{{ index + 1 }}</span>
                <span class="seq-label">{{ TEXT.modules.feeContracts.paymentSeqUnit }}</span>
              </div>
              <el-button link type="danger" :disabled="isFormReadOnly" @click="removePayment(index)" class="remove-btn">
                <el-icon><Delete /></el-icon>
              </el-button>
            </div>

            <div class="payment-card-body">
              <div class="field-grid field-grid--3">
                <el-form-item :label="`${TEXT.common.fields.amount}（万元）`" :error="paymentErrors[index]?.amount">
                  <el-input-number v-model="payment.amount" :disabled="isFormReadOnly" :min="0" :precision="2" class="full-width" controls-position="right" />
                </el-form-item>
                <el-form-item :label="TEXT.modules.feeContracts.paidFlag" :error="paymentErrors[index]?.paid_date">
                  <div class="status-row">
                    <el-checkbox v-model="payment.is_paid" :disabled="isFormReadOnly" @change="() => onPaidToggle(payment)">
                      {{ TEXT.modules.feeContracts.isPaid }}
                    </el-checkbox>
                    <el-date-picker
                      v-if="payment.is_paid"
                      v-model="payment.paid_date"
                      type="date"
                      value-format="YYYY-MM-DD"
                      :placeholder="TEXT.common.placeholders.select"
                      :disabled="isFormReadOnly"
                      class="status-datepicker"
                      size="small"
                    />
                  </div>
                </el-form-item>
                <el-form-item :label="TEXT.modules.feeContracts.verifiedFlag" :error="paymentErrors[index]?.verified_date">
                  <div class="status-row">
                    <el-checkbox v-model="payment.is_verified" :disabled="isFormReadOnly" @change="() => onVerifiedToggle(payment)">
                      {{ TEXT.modules.feeContracts.isVerified }}
                    </el-checkbox>
                    <el-date-picker
                      v-if="payment.is_verified"
                      v-model="payment.verified_date"
                      type="date"
                      value-format="YYYY-MM-DD"
                      :placeholder="TEXT.common.placeholders.select"
                      :disabled="isFormReadOnly"
                      class="status-datepicker"
                      size="small"
                    />
                  </div>
                </el-form-item>
              </div>
              <el-form-item :label="TEXT.common.fields.remark" class="mb-0">
                <el-input v-model="payment.remark" :disabled="isFormReadOnly" type="textarea" :rows="2" :placeholder="TEXT.common.placeholders.input" />
              </el-form-item>
            </div>

            <div v-if="paymentErrors[index]?.verification" class="payment-error">
              {{ paymentErrors[index].verification }}
            </div>
          </div>
        </div>
      </div>

      <!-- 附件 -->
      <div class="form-section">
        <div class="form-section-title">
          <span class="dot dot--green" />
          {{ TEXT.modules.feeContracts.attachmentTitle }}
        </div>
        <AttachmentList
          ref="attachmentPanelRef"
          :study-id="currentStudyId"
          :entity-type="'contract_fee'"
          :entity-id="form.id"
          :entity-groups="attachmentGroups"
          :mode="'upload'"
          :readonly="isFormReadOnly"
          :center-upload-card-content="true"
          :upload-card-columns="3"
        />
      </div>
    </el-form>

    <template #footer>
      <div class="drawer-footer">
        <el-button @click="emit('update:modelValue', false)" class="footer-btn">{{ TEXT.common.actions.cancel }}</el-button>
        <el-button type="primary" :loading="saving" :disabled="isFormReadOnly || drawerLoading" @click="saveForm" class="footer-btn footer-btn--primary">{{ TEXT.common.actions.save }}</el-button>
      </div>
    </template>
  </el-drawer>
</template>

<script setup lang="ts">
import { computed, reactive, ref, watch } from "vue";
import { ElMessage, type FormInstance, type FormRules } from "element-plus";
import { Delete, Plus } from "@element-plus/icons-vue";
import {
  createContractFee,
  createContractPayment,
  deleteContractPayment,
  getContractFee,
  updateContractFee,
  updateContractPayment,
} from "../../api/feeContracts";
import { useStudyStore } from "../../store/study";
import { usePermission } from "../../utils/permission";
import { useDrawerDirtyGuard } from "../../utils/drawerDirtyGuard";
import AttachmentList from "../../components/attachments/AttachmentList.vue";
import StateError from "../../components/StateError.vue";
import StateLoading from "../../components/StateLoading.vue";
import { TEXT } from "../../locales";

type ContractFormModel = {
  id: string;
  study_id: string;
  center_id: string;
  contract_no: string;
  signed_date: string;
  contract_amount: number;
  remark: string;
  contract_cases: number;
  actual_cases: number | null;
};

type PaymentFormModel = {
  id?: string;
  tempId: string;
  amount: number;
  paid_date: string;
  verified_date: string;
  is_paid: boolean;
  is_verified: boolean;
  remark: string;
};

const props = defineProps<{
  modelValue: boolean;
  contractId?: string;
  sites: any[];
  initialCenterId?: string;
}>();

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

const study = useStudyStore();
const { can } = usePermission();
const canCreate = computed(() => can("fees.contract.create"));
const canUpdate = computed(() => can("fees.contract.update"));
const currentStudyId = computed(() => study.currentStudy?.id || "");
const drawerLoading = ref(false);
const drawerErrorMessage = ref("");
const saving = ref(false);
const formRef = ref<FormInstance>();
const attachmentPanelRef = ref<InstanceType<typeof AttachmentList> | null>(null);

const siteActiveMap = computed(() => {
  const map: Record<string, boolean> = {};
  props.sites.forEach((site) => {
    if (site?.id) map[site.id] = !!site.is_active;
  });
  return map;
});

const defaultForm: ContractFormModel = {
  id: "",
  study_id: "",
  center_id: "",
  contract_no: "",
  signed_date: "",
  contract_amount: 0,
  remark: "",
  contract_cases: 0,
  actual_cases: null,
};

const form = reactive<ContractFormModel>({ ...defaultForm });
const payments = ref<PaymentFormModel[]>([]);
const removedPaymentIds = ref<string[]>([]);
const paymentErrors = ref<Record<string, string>[]>([]);
const drawerDirtyGuard = useDrawerDirtyGuard(() => ({
  form,
  payments: payments.value,
  removedPaymentIds: removedPaymentIds.value,
  attachments: attachmentPanelRef.value?.pendingSnapshot() || [],
}));
const selectedSiteInactive = computed(() => !!props.contractId && !!form.center_id && siteActiveMap.value[form.center_id] === false);
const isFormReadOnly = computed(() => (props.contractId ? !canUpdate.value : !canCreate.value) || selectedSiteInactive.value);



const attachmentGroups = [
  {
    entityType: "contract_fee_contract",
    label: TEXT.modules.feeContracts.attachmentContract,
    uploadText: "点击上传合同",
  },
  {
    entityType: "contract_fee_voucher",
    label: TEXT.modules.feeContracts.attachmentVoucher,
    uploadText: "点击上传凭证",
  },
  {
    entityType: "contract_fee_invoice",
    label: TEXT.modules.feeContracts.attachmentInvoice,
    uploadText: "点击上传发票",
  },
];

const rules: FormRules<ContractFormModel> = {
  center_id: [{ required: true, message: TEXT.common.messages.required, trigger: "change" }],
  contract_amount: [{ required: true, type: "number", message: TEXT.common.messages.required, trigger: "change" }],
  contract_cases: [{ required: true, type: "number", message: TEXT.common.messages.required, trigger: "change" }],
};

const resetForm = () => {
  Object.assign(form, { ...defaultForm, study_id: study.currentStudy?.id || "", center_id: props.initialCenterId || "" });
  payments.value = [];
  removedPaymentIds.value = [];
  paymentErrors.value = [];
  drawerErrorMessage.value = "";
  formRef.value?.clearValidate();
};

const normalizePayment = (payment: any): PaymentFormModel => ({
  id: payment.id,
  tempId: payment.id || `${Date.now()}-${Math.random()}`,
  amount: Number(payment.amount || 0) / 10000,
  paid_date: payment.paid_date || "",
  verified_date: payment.verified_date || "",
  is_paid: !!payment.is_paid,
  is_verified: !!payment.is_verified,
  remark: payment.remark || "",
});

const loadEditingDetail = async (id: string) => {
  drawerLoading.value = true;
  drawerErrorMessage.value = "";
  try {
    const { data } = await getContractFee(id);
    const detail = data?.data || {};
    Object.assign(form, {
      id: detail.id || id,
      study_id: detail.study_id || study.currentStudy?.id || "",
      center_id: detail.center_id || "",
      contract_no: detail.contract_no || "",
      signed_date: detail.signed_date || "",
      contract_amount: Number(detail.contract_amount || 0) / 10000,
      remark: detail.remark || "",
      contract_cases: Number(detail.contract_cases || 0),
      actual_cases: detail.actual_cases ?? null,
    });
    payments.value = (detail.payments || []).map(normalizePayment);
    removedPaymentIds.value = [];
    paymentErrors.value = [];
    formRef.value?.clearValidate();
    drawerDirtyGuard.syncBaseline();
  } catch (e: any) {
    drawerErrorMessage.value = e?.response?.data?.message || TEXT.common.messages.loadFailed;
  } finally {
    drawerLoading.value = false;
  }
};

const reloadEditingDetail = () => {
  if (props.contractId) loadEditingDetail(props.contractId);
};

const addPayment = () => {
  if (isFormReadOnly.value) {
    ElMessage.warning(selectedSiteInactive.value ? "中心已停用" : "权限不足");
    return;
  }
  payments.value.push({
    tempId: `${Date.now()}-${Math.random()}`,
    amount: 0,
    paid_date: "",
    verified_date: "",
    is_paid: false,
    is_verified: false,
    remark: "",
  });
};

const removePayment = (index: number) => {
  if (isFormReadOnly.value) {
    ElMessage.warning(selectedSiteInactive.value ? "中心已停用" : "权限不足");
    return;
  }
  const payment = payments.value[index];
  if (payment?.id) {
    removedPaymentIds.value.push(payment.id);
  }
  payments.value.splice(index, 1);
};

const onPaidToggle = (payment: PaymentFormModel) => {
  if (isFormReadOnly.value) return;
  if (!payment.is_paid) {
    payment.paid_date = "";
    payment.is_verified = false;
    payment.verified_date = "";
  }
};

const onVerifiedToggle = (payment: PaymentFormModel) => {
  if (isFormReadOnly.value) return;
  if (payment.is_verified && !payment.is_paid) {
    payment.is_paid = true;
  }
  if (!payment.is_verified) {
    payment.verified_date = "";
  }
};

const validatePayments = () => {
  const errors: Record<string, string>[] = [];
  let ok = true;
  payments.value.forEach((payment, index) => {
    const entry: Record<string, string> = {};
    if (payment.amount === null || payment.amount === undefined || Number(payment.amount) < 0) {
      entry.amount = TEXT.modules.feeContracts.amountInvalid;
      ok = false;
    }
    if (payment.is_paid && !payment.paid_date) {
      entry.paid_date = TEXT.modules.feeContracts.paidDateRequired;
      ok = false;
    }
    if (payment.is_verified && !payment.verified_date) {
      entry.verified_date = TEXT.modules.feeContracts.verifiedDateRequired;
      ok = false;
    }
    if (payment.is_verified && !payment.is_paid) {
      entry.verification = TEXT.modules.feeContracts.verifyRequiresPaid;
      ok = false;
    }
    errors[index] = entry;
  });
  paymentErrors.value = errors;
  return ok;
};

const saveForm = async () => {
  const studyId = study.currentStudy?.id;
  if (!studyId) return;
  if (isFormReadOnly.value) {
    ElMessage.warning(selectedSiteInactive.value ? "中心已停用" : "权限不足");
    return;
  }
  if (form.center_id && siteActiveMap.value[form.center_id] === false) {
    ElMessage.warning("中心已停用");
    return;
  }
  const formOk = await formRef.value?.validate?.().catch(() => false);
  if (!formOk) return;
  if (!validatePayments()) {
    ElMessage.error(TEXT.modules.feeContracts.paymentValidationFailed);
    return;
  }
  saving.value = true;
  try {
    const payload = {
      study_id: studyId,
      center_id: form.center_id,
      contract_no: form.contract_no || null,
      signed_date: form.signed_date || null,
      contract_amount: Number(form.contract_amount || 0) * 10000,
      remark: form.remark || null,
      contract_cases: Number(form.contract_cases || 0),
      actual_cases: form.actual_cases === null ? null : Number(form.actual_cases),
    };
    const updatePayload = {
      contract_amount: payload.contract_amount,
      contract_no: payload.contract_no,
      signed_date: payload.signed_date,
      remark: payload.remark,
      contract_cases: payload.contract_cases,
      actual_cases: payload.actual_cases,
    };

    let savedId = props.contractId || form.id;
    if (props.contractId && savedId) {
      await updateContractFee(savedId, updatePayload);
    } else {
      const { data } = await createContractFee(payload);
      savedId = data?.data?.id;
      form.id = savedId || "";
    }

    if (savedId) {
      for (const paymentId of removedPaymentIds.value) {
        await deleteContractPayment(paymentId);
      }
      removedPaymentIds.value = [];
      for (const payment of payments.value) {
        const paymentPayload = {
          amount: Number(payment.amount || 0) * 10000,
          paid_date: payment.paid_date || null,
          verified_date: payment.verified_date || null,
          is_paid: !!payment.is_paid,
          is_verified: !!payment.is_verified,
          remark: payment.remark || null,
        };
        if (payment.id) {
          await updateContractPayment(payment.id, paymentPayload);
        } else {
          const { data } = await createContractPayment(savedId, paymentPayload);
          payment.id = data?.data?.id;
          payment.tempId = payment.id || payment.tempId;
        }
      }
      await attachmentPanelRef.value?.uploadPending(savedId);
    }

    drawerDirtyGuard.syncBaseline();
    emit("update:modelValue", false);
    emit("saved", savedId || "");
    ElMessage.success(TEXT.common.messages.saveSuccess);
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.message || e?.message || TEXT.common.messages.saveFailed);
  } finally {
    saving.value = false;
  }
};

watch(
  () => props.modelValue,
  async (visible) => {
    if (!visible) return;
    resetForm();
    if (props.contractId) {
      await loadEditingDetail(props.contractId);
    } else {
      drawerDirtyGuard.syncBaseline();
    }
  },
);
</script>

<style scoped>
/* ==================== Drawer ==================== */
:deep(.contract-fee-editor-drawer > .el-drawer__header) {
  margin-bottom: 0;
  padding: 20px 24px 8px;
}

:deep(.contract-fee-editor-drawer > .el-drawer__body) {
  padding: 0 24px 4px;
}

.editor-header {
  display: flex;
  flex-direction: column;
}

.editor-title {
  font-size: 18px;
  font-weight: 700;
  color: #0a0a0a;
  line-height: 1.2;
  letter-spacing: -0.01em;
}

/* ==================== Form ==================== */
.contract-fee-form {
  padding: 0;
}

.form-section {
  padding-bottom: 6px;
}

.form-section + .form-section {
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid #f0f0f0;
}

.form-section-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  font-weight: 600;
  color: #0a0a0a;
  margin-bottom: 16px;
}

.form-section-title--action {
  justify-content: space-between;
}

.section-title-left {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* Dots */
.dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}

.dot--blue { background: #3b82f6; }
.dot--amber { background: #f59e0b; }
.dot--green { background: #22c55e; }

/* ==================== Field Grid ==================== */
.field-grid {
  display: grid;
  gap: 0 16px;
}

.field-grid--2 {
  grid-template-columns: 1fr 1fr;
}

.field-grid--3 {
  grid-template-columns: 1fr 1fr 1fr;
}

.full-width {
  width: 100%;
}

/* ==================== Inactive Hint ==================== */
.inactive-hint {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  background: #fffbeb;
  border: 1px solid #fde68a;
  border-radius: 8px;
  font-size: 13px;
  color: #92400e;
  margin-top: 4px;
}

.hint-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #f59e0b;
  color: #ffffff;
  font-size: 12px;
  line-height: 1;
  flex-shrink: 0;
}

/* ==================== Empty State ==================== */
.section-empty {
  padding: 32px 0;
  display: flex;
  justify-content: center;
  color: #a3a3a3;
  font-size: 13px;
  font-weight: 500;
}

/* ==================== Payment Cards ==================== */
.payment-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.payment-card {
  border: 1px solid #f0f0f0;
  border-radius: 10px;
  padding: 16px 18px 14px;
  background: #fafbfc;
  transition: border-color 0.15s ease;
}

.payment-card:hover {
  border-color: #d4d4d4;
}

.payment-card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 14px;
}

.payment-card-seq {
  display: flex;
  align-items: center;
  gap: 8px;
}

.seq-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  border-radius: 4px;
  background: #f0f0f0;
  color: #525252;
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
}

.seq-label {
  font-size: 14px;
  font-weight: 600;
  color: #0a0a0a;
}

.remove-btn {
  font-size: 13px;
}

.payment-card-body {
  display: flex;
  flex-direction: column;
  gap: 0;
}

/* Status row (checkbox + date picker) */
.status-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.status-datepicker {
  width: auto;
  min-width: 0;
  flex: 1;
}

.status-datepicker :deep(.el-date-editor.el-input),
.status-datepicker :deep(.el-input__wrapper) {
  width: 100%;
  min-width: 0;
}

/* ==================== Payment Error ==================== */
.payment-error {
  color: #dc2626;
  font-size: 12px;
  margin-top: 10px;
  padding: 6px 10px;
  background: #fef2f2;
  border-radius: 6px;
}

.mb-0 {
  margin-bottom: 0 !important;
}

/* ==================== Footer ==================== */
.drawer-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.footer-btn {
  height: 36px;
  border-radius: 8px;
  padding: 0 20px;
  font-size: 13px;
  font-weight: 500;
}

.footer-btn--primary {
  padding: 0 24px;
}

/* ==================== Element Overrides ==================== */
.contract-fee-form :deep(.el-form-item) {
  margin-bottom: 14px;
}

.contract-fee-form :deep(.el-form-item__label) {
  font-size: 12px;
  font-weight: 600;
  color: #525252;
  padding-bottom: 4px;
}

.contract-fee-form :deep(.el-form-item__error) {
  font-size: 11px;
}

.add-payment-btn {
  height: 28px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 500;
  padding: 0 10px;
}

/* ==================== Responsive ==================== */
@media (max-width: 700px) {
  .field-grid--2,
  .field-grid--3 {
    grid-template-columns: 1fr;
  }
}
</style>
