<template>
  <div class="page">
    <StateError v-if="errorMessage" :description="errorMessage">
      <template #action>
        <el-button type="primary" @click="loadDetail">{{ TEXT.common.actions.retry }}</el-button>
      </template>
    </StateError>

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

    <template v-else>
        <el-form ref="formRef" :model="form" :rules="rules" label-width="140px" label-position="top">
          <el-card class="form-card unified-shell" shadow="never">
          <template #header>
            <div class="card-header actions-header">
              <span class="header-title">{{ TEXT.common.labels.basicInfo }}</span>
              <el-button @click="goBack">{{ TEXT.common.actions.back }}</el-button>
            </div>
          </template>
          <el-row :gutter="24">
            <el-col :span="12">
              <el-form-item :label="TEXT.common.fields.site" prop="center_id" required>
                <el-select
                  v-model="form.center_id"
                  :disabled="isEdit || isReadOnly"
                  :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-col>
            <el-col :span="12">
              <el-form-item :label="TEXT.modules.feeContracts.contractAmount" prop="contract_amount" required>
                <el-input-number
                  v-model="form.contract_amount"
                  :disabled="isReadOnly"
                  :min="0"
                  :precision="2"
                  :step="1000"
                  class="full-width"
                  controls-position="right"
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item :label="TEXT.modules.feeContracts.contractCases" prop="contract_cases" required>
                <el-input-number v-model="form.contract_cases" :disabled="isReadOnly" :min="0" :step="1" class="full-width" controls-position="right" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item :label="TEXT.modules.feeContracts.actualCases" prop="actual_cases">
                <el-input-number v-model="form.actual_cases" :disabled="isReadOnly" :min="0" :step="1" class="full-width" controls-position="right" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item :label="TEXT.modules.feeContracts.settlementAmount" prop="settlement_amount">
                <el-input-number
                  v-model="form.settlement_amount"
                  :disabled="isReadOnly"
                  :min="0"
                  :precision="2"
                  :step="1000"
                  class="full-width"
                  controls-position="right"
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item :label="TEXT.modules.feeContracts.finalPaymentAmount" prop="final_payment_amount">
                <el-input-number
                  v-model="form.final_payment_amount"
                  :disabled="isReadOnly"
                  :min="0"
                  :precision="2"
                  :step="1000"
                  class="full-width"
                  controls-position="right"
                />
              </el-form-item>
            </el-col>
          </el-row>
        </el-card>

        <el-card class="form-card section-margin unified-shell" shadow="never">
          <template #header>
            <div class="card-header actions-header">
              <span class="header-title">{{ TEXT.modules.feeContracts.paymentTitle }}</span>
              <el-button type="primary" :disabled="isReadOnly" @click="addPayment">
                <el-icon class="el-icon--left"><Plus /></el-icon>
                {{ TEXT.common.actions.add }}
              </el-button>
            </div>
          </template>

          <div v-if="payments.length === 0" class="section-empty">
            <StateEmpty :description="TEXT.modules.feeContracts.paymentEmpty" />
          </div>
          
          <div v-else class="payment-list">
            <transition-group name="list">
              <div v-for="(payment, index) in payments" :key="payment.tempId" class="payment-item">
                <div class="payment-item-header">
                  <div class="payment-seq">
                    <span class="seq-circle">{{ index + 1 }}</span>
                    <span class="seq-text">{{ TEXT.modules.feeContracts.paymentSeqUnit }}</span>
                  </div>
                  <el-button link type="danger" :disabled="isReadOnly" @click="removePayment(index)">
                    <el-icon><Delete /></el-icon>
                  </el-button>
                </div>
                
                <el-row :gutter="16">
                  <el-col :span="8">
                    <el-form-item :label="TEXT.common.fields.amount" :error="paymentErrors[index]?.amount">
                      <el-input-number v-model="payment.amount" :disabled="isReadOnly" :min="0" :precision="2" class="full-width" controls-position="right" />
                    </el-form-item>
                  </el-col>
                  <el-col :span="8">
                    <el-form-item :label="TEXT.modules.feeContracts.paidFlag" :error="paymentErrors[index]?.paid_date">
                      <div class="status-control">
                        <el-checkbox v-model="payment.is_paid" :disabled="isReadOnly" @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="isReadOnly"
                          class="status-picker"
                          size="small"
                        />
                      </div>
                    </el-form-item>
                  </el-col>
                  <el-col :span="8">
                    <el-form-item :label="TEXT.modules.feeContracts.verifiedFlag" :error="paymentErrors[index]?.verified_date">
                      <div class="status-control">
                        <el-checkbox v-model="payment.is_verified" :disabled="isReadOnly" @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="isReadOnly"
                          class="status-picker"
                          size="small"
                        />
                      </div>
                    </el-form-item>
                  </el-col>
                </el-row>
                
                <el-form-item :label="TEXT.common.fields.remark" class="mb-0">
                  <el-input v-model="payment.remark" :disabled="isReadOnly" type="textarea" :rows="2" :placeholder="TEXT.common.placeholders.input" />
                </el-form-item>
                
                <div v-if="paymentErrors[index]?.verification" class="payment-error">
                  {{ paymentErrors[index].verification }}
                </div>
              </div>
            </transition-group>
          </div>
        </el-card>

        <el-card class="form-card section-margin unified-shell" shadow="never">
          <template #header>
            <div class="card-header">
              <span class="header-title">{{ TEXT.modules.feeContracts.attachmentTitle }}</span>
            </div>
          </template>
          <FeeAttachmentPanel
            v-if="form.id"
            :entity-type="'contract_fee'"
            :entity-id="form.id"
            :groups="attachmentGroups"
            :readonly="isReadOnly"
          />

          <StateEmpty v-else :description="TEXT.modules.feeContracts.uploadHint" class="compact-empty" />
        </el-card>

        <div class="footer-actions">
          <el-button @click="goBack">{{ TEXT.common.actions.cancel }}</el-button>
          <el-button type="primary" :loading="saving" :disabled="isReadOnly" @click="submit" class="save-btn">
            {{ TEXT.common.actions.save }}
          </el-button>
        </div>
      </el-form>
    </template>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive, ref } from "vue";
import { useRoute, useRouter } from "vue-router";
import { ElMessage } from "element-plus";
import { Plus, Delete } from "@element-plus/icons-vue";
import {
  createContractFee,
  createContractPayment,
  deleteContractPayment,
  getContractFee,
  updateContractFee,
  updateContractPayment,
} from "../../api/feeContracts";
import { fetchSites } from "../../api/sites";
import { useStudyStore } from "../../store/study";
import StateEmpty from "../../components/StateEmpty.vue";
import StateError from "../../components/StateError.vue";
import StateLoading from "../../components/StateLoading.vue";
import FeeAttachmentPanel from "../../components/fees/FeeAttachmentPanel.vue";
import { TEXT } from "../../locales";

const route = useRoute();
const router = useRouter();
const study = useStudyStore();

const loading = ref(false);
const saving = ref(false);
const errorMessage = ref("");
const sites = ref<any[]>([]);
const siteActiveMap = computed(() => {
  const map: Record<string, boolean> = {};
  sites.value.forEach((site) => {
    if (site?.id) map[site.id] = !!site.is_active;
  });
  return map;
});
const isReadOnly = computed(() => isEdit.value && !!form.center_id && siteActiveMap.value[form.center_id] === false);

const formRef = ref();
const form = reactive({
  id: "",
  project_id: "",
  center_id: "",
  contract_amount: 0,
  contract_cases: 0,
  actual_cases: null as number | null,
  settlement_amount: null as number | null,
  final_payment_amount: null as number | null,
});

const payments = ref<any[]>([]);
const removedPaymentIds = ref<string[]>([]);
const paymentErrors = ref<Record<string, string>[]>([]);

const contractId = computed(() => route.params.contractId as string | undefined);
const isEdit = computed(() => !!contractId.value);

const attachmentGroups = [
  {
    key: "contract",
    label: TEXT.modules.feeContracts.attachmentContract,
    description: TEXT.modules.feeContracts.attachmentContractDesc,
    emptyText: TEXT.modules.feeContracts.attachmentContractEmpty,
  },
  {
    key: "voucher",
    label: TEXT.modules.feeContracts.attachmentVoucher,
    description: TEXT.modules.feeContracts.attachmentVoucherDesc,
    emptyText: TEXT.modules.feeContracts.attachmentVoucherEmpty,
  },
  {
    key: "invoice",
    label: TEXT.modules.feeContracts.attachmentInvoice,
    description: TEXT.modules.feeContracts.attachmentInvoiceDesc,
    emptyText: TEXT.modules.feeContracts.attachmentInvoiceEmpty,
  },
];

const rules = {
  center_id: [{ required: true, message: TEXT.common.messages.required, trigger: "change" }],
  contract_amount: [{ required: true, message: TEXT.common.messages.required, trigger: "blur" }],
  contract_cases: [{ required: true, message: TEXT.common.messages.required, trigger: "blur" }],
};

const loadSites = async () => {
  const studyId = study.currentStudy?.id;
  if (!studyId) return;
  try {
    const { data } = await fetchSites(studyId, { limit: 500 });
    sites.value = Array.isArray(data) ? data : data.items || [];
  } catch {
    sites.value = [];
  }
};

const loadDetail = async () => {
  if (!contractId.value) return;
  loading.value = true;
  errorMessage.value = "";
  removedPaymentIds.value = [];
  paymentErrors.value = [];
  try {
    const { data } = await getContractFee(contractId.value);
    const detail = data?.data || {};
    Object.assign(form, {
      id: detail.id || contractId.value,
      project_id: detail.project_id || study.currentStudy?.id || "",
      center_id: detail.center_id || "",
      contract_amount: Number(detail.contract_amount || 0) / 10000,
      contract_cases: Number(detail.contract_cases || 0),
      actual_cases: detail.actual_cases ?? null,
      settlement_amount: detail.settlement_amount !== null && detail.settlement_amount !== undefined ? Number(detail.settlement_amount) / 10000 : null,
      final_payment_amount: detail.final_payment_amount !== null && detail.final_payment_amount !== undefined ? Number(detail.final_payment_amount) / 10000 : null,
    });
    payments.value = (detail.payments || []).map((payment: any) => ({
      id: payment.id,
      tempId: payment.id,
      amount: Number(payment.amount || 0),
      paid_date: payment.paid_date || "",
      verified_date: payment.verified_date || "",
      is_paid: !!payment.is_paid,
      is_verified: !!payment.is_verified,
      remark: payment.remark || "",
    }));
  } catch (e: any) {
    errorMessage.value = e?.response?.data?.message || TEXT.common.messages.loadFailed;
  } finally {
    loading.value = false;
  }
};

const addPayment = () => {
  if (isReadOnly.value) {
    ElMessage.warning("中心已停用");
    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 (isReadOnly.value) {
    ElMessage.warning("中心已停用");
    return;
  }
  const payment = payments.value[index];
  if (payment?.id) {
    removedPaymentIds.value.push(payment.id);
  }
  payments.value.splice(index, 1);
};

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

const onVerifiedToggle = (payment: any) => {
  if (isReadOnly.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 submit = async () => {
  if (!study.currentStudy?.id) return;
  if (isReadOnly.value) {
    ElMessage.warning("中心已停用");
    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 = {
      project_id: study.currentStudy.id,
      center_id: form.center_id,
      contract_amount: Number(form.contract_amount || 0) * 10000,
      contract_cases: Number(form.contract_cases || 0),
      actual_cases: form.actual_cases === null ? null : Number(form.actual_cases),
      settlement_amount: form.settlement_amount === null ? null : Number(form.settlement_amount) * 10000,
      final_payment_amount: form.final_payment_amount === null ? null : Number(form.final_payment_amount) * 10000,
    };
    const updatePayload = {
      contract_amount: payload.contract_amount,
      contract_cases: payload.contract_cases,
      actual_cases: payload.actual_cases,
      settlement_amount: payload.settlement_amount,
      final_payment_amount: payload.final_payment_amount,
    };

    let savedId = contractId.value || form.id;
    if (isEdit.value && 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),
          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;
        }
      }
    }

    ElMessage.success(TEXT.common.messages.saveSuccess);
    if (savedId) {
      router.push(`/fees/contracts/${savedId}`);
    } else {
      goBack();
    }
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.message || TEXT.common.messages.saveFailed);
  } finally {
    saving.value = false;
  }
};

const goBack = () => router.push("/fees/contracts");

onMounted(async () => {
  await loadSites();
  if (isEdit.value) {
    await loadDetail();
  } else {
    form.project_id = study.currentStudy?.id || "";
  }
});
</script>

<style scoped>
.page {
  display: flex;
  flex-direction: column;
  gap: 0;
  width: 100%;
}

.form-card {
  border-radius: 12px;
  border: 1px solid var(--ctms-border-color);
  overflow: hidden;
}

.section-margin {
  margin-top: 24px;
}

.card-header {
  padding: 4px 0;
}

.actions-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-title {
  font-size: 16px;
  font-weight: 600;
  color: var(--ctms-text-main);
  border-left: 4px solid var(--el-color-primary);
  padding-left: 12px;
}

.full-width {
  width: 100%;
}

.section-empty {
  padding: 24px 0;
  display: flex;
  justify-content: center;
}

.payment-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.payment-item {
  border: 1px solid var(--ctms-border-color);
  border-radius: 8px;
  padding: 16px;
  background-color: var(--ctms-bg-color-page);
  transition: all 0.3s;
}

.payment-item:hover {
  border-color: var(--ctms-border-color-hover);
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
}

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

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

.seq-circle {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background-color: var(--el-color-primary);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 600;
}

.seq-text {
  font-size: 14px;
  font-weight: 500;
  color: var(--ctms-text-main);
}

.status-control {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.status-picker {
  width: 100%;
}

.payment-error {
  color: var(--ctms-danger);
  font-size: 12px;
  margin-top: 8px;
}

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

.footer-actions {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 24px;
  padding-bottom: 32px;
}

.save-btn {
  padding: 0 32px;
}

.list-enter-active,
.list-leave-active {
  transition: all 0.3s ease;
}
.list-enter-from,
.list-leave-to {
  opacity: 0;
  transform: translateY(-20px);
}

.compact-empty :deep(.state) {
  padding: 24px 0 !important;
  flex-direction: row;
  gap: 12px;
}
.compact-empty :deep(.state-icon) {
  font-size: 24px !important;
  margin-bottom: 0 !important;
}
.compact-empty :deep(.state-title) {
  font-size: 14px !important;
  font-weight: normal !important;
  margin: 0 !important;
}
.compact-empty :deep(.state-desc) {
  margin: 0 !important;
  font-size: 14px !important;
}
</style>
