<template>
  <div class="p-3">
    <!-- TimeOption Filter -->
    <TimeOption
      v-bind="{
        pagename: 'debt_report',
        api: 'transaction',
        timeopt: { time: 36000, disable: ['add'] },
        filter: { phase: 3 },
      }"
      @option="handleTimeOption"
      @excel="exportExcel"
      @refresh-data="loadData"
      class="mb-3"
    />

    <!-- Loading -->
    <div
      v-if="loading"
      class="has-text-centered py-6"
    >
      <p class="has-text-grey mb-3">Đang tải dữ liệu...</p>
      <progress
        class="progress is-small is-primary"
        max="100"
      ></progress>
    </div>

    <div
      class=""
      v-else
    >
      <!-- Table -->
      <div
        v-if="filteredRows.length > 0"
        class="table-container"
        style="overflow-x: auto; max-width: 100%"
      >
        <table class="table is-bordered is-striped is-narrow is-hoverable is-fullwidth debt-table">
          <thead>
            <tr>
              <!-- Fixed columns (sticky left) -->
              <th
                rowspan="2"
                class="fixed-col has-background-primary has-text-white has-text-centered"
              >
                STT
              </th>
              <th
                rowspan="2"
                class="fixed-col has-background-primary has-text-white"
              >
                Mã KH
              </th>
              <th
                rowspan="2"
                class="fixed-col has-background-primary has-text-white"
              >
                Mã Căn
              </th>
              <th
                rowspan="2"
                class="fixed-col has-background-primary has-text-white"
              >
                Ngày ký HĐ
              </th>
              <th
                rowspan="2"
                class="fixed-col has-background-primary has-text-white"
              >
                Giá trị HĐMB
              </th>
              <th
                rowspan="2"
                class="fixed-col has-background-primary has-text-white"
              >
                Tiền nộp theo HĐV/TTTHNV
              </th>
              <th
                rowspan="2"
                class="fixed-col has-background-primary has-text-white"
              >
                Tỷ lệ
              </th>

              <!-- Scrollable columns -->
              <th
                v-for="(sch, si) in scheduleHeaders"
                :key="si"
                :colspan="6"
                class="has-text-centered has-background-primary has-text-white"
              >
                {{ sch.label }}
              </th>

              <th
                rowspan="2"
                class="has-background-primary has-text-white"
              >
                Số tiền quá hạn
              </th>
            </tr>

            <tr>
              <template
                v-for="(sch, si) in scheduleHeaders"
                :key="si"
              >
                <th class="has-background-primary has-text-white sub-header">Ngày</th>
                <th class="has-background-primary has-text-white sub-header">Số tiền</th>
                <th class="has-background-primary has-text-white sub-header">Lũy kế sang đợt</th>
                <th class="has-background-primary has-text-white sub-header">Số tiền đã thực thanh toán</th>
                <th class="has-background-primary has-text-white sub-header">Tỷ lệ</th>
                <th class="has-background-primary has-text-white sub-header-remain">Dư nợ</th>
              </template>
            </tr>
          </thead>

          <tbody>
            <tr
              v-for="(row, ri) in filteredRows"
              :key="ri"
            >
              <!-- Fixed columns -->
              <td class="fixed-col has-text-centered">{{ ri + 1 }}</td>
              <td class="fixed-col">{{ row.customer_code }}</td>
              <td class="fixed-col has-text-weight-semibold has-text-primary">
                {{ row.trade_code }}
              </td>
              <td class="fixed-col">{{ row.contract_date }}</td>
              <td class="fixed-col has-text-right">
                {{ fmt(row.sale_price) }}
              </td>
              <td class="fixed-col has-text-right has-text-weight-semibold has-background-warning-light">
                {{ fmt(row.ttthnv_paid) }}
              </td>
              <td class="fixed-col has-text-right has-background-success-light">
                {{ pct(row.ttthnv_paid, row.sale_price) }}
              </td>

              <!-- Scrollable columns -->
              <template
                v-for="(sch, si) in scheduleHeaders"
                :key="si"
              >
                <template v-if="row.schedules[si]">
                  <td>{{ row.schedules[si].to_date }}</td>
                  <td class="has-text-right">
                    {{ fmt(row.schedules[si].amount) }}
                  </td>
                  <td class="has-text-right has-text-info">
                    {{ fmt(row.schedules[si].luy_ke_sang_dot) }}
                  </td>
                  <td class="has-text-right has-text-weight-semibold has-text-success">
                    {{ fmt(row.schedules[si].thuc_thanh_toan) }}
                  </td>
                  <td
                    class="has-text-right"
                    :class="pctClass(row.schedules[si].thuc_thanh_toan, row.schedules[si].amount)"
                  >
                    {{ pct(row.schedules[si].thuc_thanh_toan, row.schedules[si].amount) }}
                  </td>
                  <td
                    class="has-text-right has-text-weight-semibold"
                    :class="Number(row.schedules[si].amount_remain) > 0 ? 'has-text-danger' : 'has-text-success'"
                  >
                    {{ fmt(row.schedules[si].amount_remain) }}
                  </td>
                </template>
                <template v-else>
                  <td
                    colspan="6"
                    class="has-text-centered has-text-grey-light"
                    style="font-style: italic"
                  >
                    —
                  </td>
                </template>
              </template>

              <td
                class="has-text-right has-text-weight-bold"
                :class="Number(row.overdue) > 0 ? 'has-background-danger-light' : ''"
              >
                {{ Number(row.overdue) > 0 ? fmt(row.overdue) : "—" }}
              </td>
            </tr>
          </tbody>

          <tfoot>
            <tr class="has-background-light">
              <td
                :colspan="7"
                class="fixed-col has-text-right has-text-weight-bold"
              >
                TỔNG CỘNG:
              </td>

              <template
                v-for="(sch, si) in scheduleHeaders"
                :key="si"
              >
                <td></td>
                <td class="has-text-right has-text-weight-semibold">
                  {{ fmt(colSum(si, "amount")) }}
                </td>
                <td></td>
                <td class="has-text-right has-text-weight-semibold has-text-success">
                  {{ fmt(colSum(si, "thuc_thanh_toan")) }}
                </td>
                <td></td>
                <td class="has-text-right has-text-weight-semibold has-text-danger">
                  {{ fmt(colSum(si, "amount_remain")) }}
                </td>
              </template>

              <td class="has-text-right has-text-weight-bold has-text-danger">
                {{ fmt(totalOverdue) }}
              </td>
            </tr>
          </tfoot>
        </table>
      </div>

      <!-- Empty -->
      <div
        v-else
        class="has-text-centered py-6"
      >
        <p class="has-text-grey">Không có dữ liệu</p>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from "vue";
import TimeOption from "~/components/datatable/TimeOption";
const { $findapi, $getapi, $dayjs, $copy } = useNuxtApp();

const loading = ref(false);
const rows = ref([]);
const filteredRows = ref([]);
const scheduleHeaders = ref([]);

const currentFilter = ref(null);
const currentSearch = ref(null);

function handleTimeOption(option) {
  if (!option) {
    currentFilter.value = null;
    currentSearch.value = null;
    applyFilters();
    return;
  }

  if (option.filter) {
    currentFilter.value = option.filter;
    currentSearch.value = null;
    applyFilters();
  } else if (option.filter_or) {
    currentFilter.value = null;
    currentSearch.value = option.filter_or;
    applyFilters();
  }
}

function applyFilters() {
  let filtered = [...rows.value];

  if (currentFilter.value && currentFilter.value.create_time__date__gte) {
    const filterDate = new Date(currentFilter.value.create_time__date__gte);
    filtered = filtered.filter((row) => {
      const contractDate = row.contract_date_raw ? new Date(row.contract_date_raw) : null;
      return contractDate && contractDate >= filterDate;
    });
  }

  if (currentSearch.value) {
    const searchTerms = Object.values(currentSearch.value).map((v) =>
      String(v).toLowerCase().replace("__icontains", ""),
    );
    filtered = filtered.filter((row) => {
      const searchableText = [
        row.customer_code,
        row.customer_name,
        row.trade_code,
        row.contract_date,
        String(row.sale_price),
      ]
        .join(" ")
        .toLowerCase();
      return searchTerms.some((term) => searchableText.includes(term));
    });
  }

  filteredRows.value = filtered;
}

async function loadData() {
  loading.value = true;
  rows.value = [];
  filteredRows.value = [];
  scheduleHeaders.value = [];

  try {
    const txnConn = $copy($findapi("transaction"));
    txnConn.params = {
      filter: { phase: 3 },
      values:
        "id,code,date,customer,customer__code,customer__fullname,sale_price,amount_received,amount_remain,product,product__trade_code,phase",
      sort: "id",
    };

    const detailConn = $copy($findapi("reservation"));
    detailConn.params = {
      filter: { transaction__phase: 3, phase: 3 },
      values: "id,transaction,phase,amount,amount_received,amount_remaining,status",
      sort: "transaction",
    };

    const schConn = $copy($findapi("payment_schedule"));
    schConn.params = {
      filter: { txn_detail__phase: 3 },
      values:
        "id,code,cycle,to_date,from_date,amount,paid_amount,amount_remain,remain_amount,status,status__name,txn_detail,txn_detail__transaction,txn_detail__phase,txn_detail__amount_received",
      sort: "txn_detail__transaction,cycle",
    };

    const ttthnvConn = $copy($findapi("reservation"));
    ttthnvConn.params = {
      filter: { transaction__phase: 3, phase: 4 },
      values: "id,transaction,phase,amount,amount_received,amount_remaining,status",
      sort: "transaction",
    };

    const [txnRs, detailRs, schRs, ttthnvRs] = await $getapi([txnConn, detailConn, schConn, ttthnvConn]);

    const transactions = txnRs?.data?.rows || [];
    const details = detailRs?.data?.rows || [];
    const schedules = schRs?.data?.rows || [];
    const ttthnvList = ttthnvRs?.data?.rows || [];

    if (!transactions.length) {
      loading.value = false;
      return;
    }

    // TTTHNV map
    const ttthnvMap = {};
    ttthnvList.forEach((t) => {
      const tid = t.transaction;
      ttthnvMap[tid] = (ttthnvMap[tid] || 0) + Number(t.amount_received || 0);
    });

    // Group schedules by transaction
    const schByTxn = {};
    schedules.forEach((s) => {
      const tid = s.txn_detail__transaction;
      if (!schByTxn[tid]) schByTxn[tid] = [];
      schByTxn[tid].push(s);
    });

    // Tìm số đợt tối đa
    let maxCycles = 0;
    Object.values(schByTxn).forEach((list) => {
      const paymentList = list.filter((s) => Number(s.cycle) > 0);
      if (paymentList.length > maxCycles) maxCycles = paymentList.length;
    });

    scheduleHeaders.value = Array.from({ length: maxCycles }, (_, i) => ({
      label: `L0${i + 1}`,
      index: i,
    }));

    rows.value = transactions.map((txn) => {
      const txnSchedules = (schByTxn[txn.id] || [])
        .filter((s) => Number(s.cycle) > 0)
        .sort((a, b) => Number(a.cycle) - Number(b.cycle));

      const ttthnvPaid = ttthnvMap[txn.id] || 0;
      const salePriceNum = Number(txn.sale_price || 0);

      // ───────────────────────────────────────────────
      // QUAN TRỌNG: Theo yêu cầu mới nhất của bạn
      // Lũy kế HĐCN = TTTHNV
      const luyKe = ttthnvPaid;
      // ───────────────────────────────────────────────

      // Phân bổ TTTHNV dần vào từng đợt → tính lũy kế sang đợt
      let remainingTTTHNV = ttthnvPaid;

      const schedulesWithCalc = txnSchedules.map((sch) => {
        const scheduleAmount = Number(sch.amount || 0);

        // Lũy kế sang đợt = min(remaining TTTHNV, số tiền đợt)
        const luyKeSangDot = Math.min(remainingTTTHNV, scheduleAmount);

        // Số tiền đã thực thanh toán = paid_amount - lũy kế sang đợt
        const paidAmountFromSchedule = Number(sch.paid_amount || 0);
        const thucThanhToan = Math.max(0, paidAmountFromSchedule - luyKeSangDot);

        // Dư nợ = số tiền đợt - lũy kế sang đợt - thực thanh toán
        const amountRemain = Math.max(0, scheduleAmount - luyKeSangDot - thucThanhToan);

        remainingTTTHNV -= luyKeSangDot;
        remainingTTTHNV = Math.max(0, remainingTTTHNV);

        return {
          to_date: sch.to_date ? $dayjs(sch.to_date).format("L") : "—",
          amount: scheduleAmount,
          luy_ke_sang_dot: luyKeSangDot,
          thuc_thanh_toan: thucThanhToan,
          amount_remain: amountRemain,
          status: sch.status,
        };
      });

      // Tính quá hạn
      const todayDate = new Date();
      const overdue = txnSchedules.reduce((sum, sch, idx) => {
        const toDate = sch.to_date ? new Date(sch.to_date) : null;
        const remain = schedulesWithCalc[idx]?.amount_remain || 0;
        if (toDate && toDate < todayDate && remain > 0) {
          return sum + remain;
        }
        return sum;
      }, 0);

      const paddedSchedules = Array.from({ length: maxCycles }, (_, i) => schedulesWithCalc[i] || null);

      return {
        customer_code: txn.customer__code || "",
        customer_name: txn.customer__fullname || "",
        trade_code: txn.product__trade_code || txn.code || "",
        contract_date: txn.date ? $dayjs(txn.date).format("L") : "—",
        contract_date_raw: txn.date,
        sale_price: salePriceNum,
        ttthnv_paid: ttthnvPaid,
        luy_ke: luyKe, // ← chính là TTTHNV
        schedules: paddedSchedules,
        overdue: overdue,
      };
    });

    filteredRows.value = rows.value;
  } catch (e) {
    console.error("BaoCaoCongNo error:", e);
  } finally {
    loading.value = false;
  }
}

function fmt(val) {
  const n = Number(val);
  if (isNaN(n) || (!n && n !== 0)) return "—";
  return n.toLocaleString("vi-VN");
}

function pct(num, denom) {
  const n = Number(num);
  const d = Number(denom);
  if (!d || isNaN(n)) return "—";
  return ((n / d) * 100).toFixed(1) + "%";
}

function pctClass(paid, amount) {
  const p = Number(paid);
  const a = Number(amount);
  if (isNaN(p) || isNaN(a) || !a) return "";
  const ratio = p / a;
  if (ratio >= 1) return "has-text-success";
  if (ratio >= 0.5) return "has-text-info";
  return "has-text-danger";
}

function colSum(scheduleIndex, field) {
  return filteredRows.value.reduce((sum, row) => {
    const sch = row.schedules[scheduleIndex];
    return sum + (sch ? Number(sch[field] || 0) : 0);
  }, 0);
}

const totalOverdue = computed(() => filteredRows.value.reduce((s, r) => s + Number(r.overdue || 0), 0));

function exportExcel() {
  const headers = [
    "STT",
    "Mã KH",
    "Mã Căn",
    "Ngày ký HĐ",
    "Giá trị HĐMB",
    "Tiền nộp TTTHNV",
    "Lũy kế tiền về HĐCN",
    "Tỷ lệ HĐCN",
  ];

  scheduleHeaders.value.forEach((h) => {
    headers.push(
      `${h.label} - Ngày`,
      `${h.label} - Số tiền`,
      `${h.label} - Lũy kế sang`,
      `${h.label} - Số tiền đã thực thanh toán`,
      `${h.label} - Tỷ lệ`,
      `${h.label} - Dư nợ`,
    );
  });

  headers.push("Số tiền quá hạn");

  const data = filteredRows.value.map((row, i) => {
    const base = [
      i + 1,
      row.customer_code,
      row.trade_code,
      row.contract_date,
      fmt(row.sale_price),
      fmt(row.ttthnv_paid),
      fmt(row.luy_ke),
      pct(row.luy_ke, row.sale_price),
    ];

    scheduleHeaders.value.forEach((_, si) => {
      const sch = row.schedules[si];
      if (sch) {
        base.push(
          sch.to_date,
          fmt(sch.amount),
          fmt(sch.luy_ke_sang_dot),
          fmt(sch.thuc_thanh_toan),
          pct(sch.thuc_thanh_toan, sch.amount),
          fmt(sch.amount_remain),
        );
      } else {
        base.push("", "", "", "", "", "");
      }
    });

    base.push(fmt(row.overdue));
    return base;
  });

  const csvRows = [headers, ...data];
  const csv = csvRows.map((r) => r.map((c) => `"${String(c ?? "").replace(/"/g, '""')}"`).join(",")).join("\n");

  const BOM = "\uFEFF";
  const blob = new Blob([BOM + csv], { type: "text/csv;charset=utf-8;" });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = `bao-cao-cong-no-${$dayjs().format("YYYYMMDD")}.csv`;
  a.click();
  URL.revokeObjectURL(url);
}

onMounted(() => loadData());
</script>

<style scoped>
/* Fixed columns style */
.fixed-col {
  position: sticky;
  left: 0;
  z-index: 3;
  background-color: white; /* nền trắng cho body */
  min-width: 80px; /* điều chỉnh theo nhu cầu */
}

/* Cột STT thường hẹp hơn */
.fixed-col:nth-child(1) {
  left: 0;
  min-width: 50px;
  z-index: 4; /* cao hơn để đè lên */
}

/* Cột Mã KH */
.fixed-col:nth-child(2) {
  left: 50px;
  min-width: 100px;
}

/* Cột Mã Căn */
.fixed-col:nth-child(3) {
  left: 150px;
  min-width: 120px;
}

/* Cột Ngày ký HĐ */
.fixed-col:nth-child(4) {
  left: 270px;
  min-width: 110px;
}

/* Cột Giá trị HĐMB */
.fixed-col:nth-child(5) {
  left: 380px;
  min-width: 140px;
}

/* Cột Tiền nộp TTTHNV */
.fixed-col:nth-child(6) {
  left: 520px;
  min-width: 160px;
}

/* Cột Lũy kế HĐCN */
.fixed-col:nth-child(7) {
  left: 680px;
  min-width: 160px;
}

/* Cột Tỷ lệ */
.fixed-col:nth-child(8) {
  left: 840px;
  min-width: 90px;
  border-right: 2px solid #dee2e6 !important; /* tạo đường phân cách rõ ràng */
}

/* Header fixed */
.debt-table thead .fixed-col {
  position: sticky;
  top: 0;
  z-index: 5;
  background-color: #204853 !important; /* primary color */
  color: white !important;
}

/* Footer fixed columns */
.debt-table tfoot .fixed-col {
  background-color: #f8f9fa !important;
  font-weight: bold;
}

/* Đảm bảo tfoot cũng có z-index */
.debt-table tfoot tr {
  z-index: 2;
}

/* Optional: bóng nhẹ khi scroll để dễ nhận biết fixed */
.fixed-col {
  box-shadow: 2px 0 5px rgba(0, 0, 0, 0.08);
}
</style>
