<template>
  <div class="p-3">
    <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"
    />

    <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>
      <div
        v-if="filteredRows.length > 0"
        class="table-container fs-15"
        style="overflow-x: auto; max-width: 100%"
      >
        <table class="table is-bordered is-striped is-narrow is-hoverable is-fullwidth debt-table">
          <thead>
            <tr>
              <th rowspan="2" class="fixed-col has-background-primary has-text-white">Mã Căn</th>
              <th rowspan="2" class="has-background-primary has-text-white">STT</th>
              <th rowspan="2" class="has-background-primary has-text-white">Mã KH</th>
              <th rowspan="2" class="has-background-primary has-text-white">Ngày ký HĐ</th>
              <th rowspan="2" class="has-background-primary has-text-white">Giá trị HĐMB</th>

              <!-- TTTHNV schedules (phase 4) -->
              <th
                v-for="(sch, si) in ttthnvScheduleHeaders"
                :key="'ttthnv-h-' + 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">Tiền nộp theo HĐV/TTTHNV</th>
              <th rowspan="2" class="has-background-primary has-text-white">Tỷ lệ</th>

              <!-- HĐCN schedules (phase 3) -->
              <th
                v-for="(sch, si) in scheduleHeaders"
                :key="'hd-h-' + si"
                :colspan="7"
                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>
              <!-- Sub-headers TTTHNV -->
              <template v-for="(sch, si) in ttthnvScheduleHeaders" :key="'ttthnv-sub-' + 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">Đã 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>
                <th class="has-background-primary has-text-white sub-header">Lãi phạt</th>
              </template>

              <!-- Sub-headers HĐCN -->
              <template v-for="(sch, si) in scheduleHeaders" :key="'hd-sub-' + 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>
                <th class="has-background-primary has-text-white sub-header">Lãi phạt</th>
              </template>
            </tr>
          </thead>

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

              <!-- TTTHNV schedule cells -->
              <template v-for="(sch, si) in ttthnvScheduleHeaders" :key="'ttthnv-row-' + si">
                <template v-if="row.ttthnvSchedules[si]">
                  <td>{{ row.ttthnvSchedules[si].to_date }}</td>
                  <td class="has-text-right">{{ fmt(row.ttthnvSchedules[si].amount) }}</td>
                  <td class="has-text-right has-text-weight-semibold has-text-success">
                    {{ fmt(row.ttthnvSchedules[si].paid_amount) }}
                  </td>
                  <td
                    class="has-text-right"
                    :class="pctClass(row.ttthnvSchedules[si].paid_amount, row.ttthnvSchedules[si].amount)"
                  >
                    {{ pct(row.ttthnvSchedules[si].paid_amount, row.ttthnvSchedules[si].amount) }}
                  </td>
                  <td
                    class="has-text-right has-text-weight-semibold"
                    :class="Number(row.ttthnvSchedules[si].amount_remain) > 0 ? 'has-text-danger' : 'has-text-success'"
                  >
                    {{ fmt(row.ttthnvSchedules[si].amount_remain) }}
                  </td>
                  <td
                    class="has-text-right has-text-weight-semibold"
                    :class="Number(row.ttthnvSchedules[si].penalty_remain) > 0 ? 'has-text-danger' : ''"
                  >
                    {{ Number(row.ttthnvSchedules[si].penalty_remain) > 0 ? fmt(row.ttthnvSchedules[si].penalty_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-semibold has-background-warning-light">
                {{ fmt(row.ttthnv_paid) }}
              </td>
              <td class="has-text-right has-background-success-light">
                {{ pct(row.ttthnv_paid, row.sale_price) }}
              </td>

              <!-- HĐCN schedule cells -->
              <template v-for="(sch, si) in scheduleHeaders" :key="'hd-row-' + 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>
                  <td
                    class="has-text-right has-text-weight-semibold"
                    :class="Number(row.schedules[si].penalty_remain) > 0 ? 'has-text-danger' : ''"
                  >
                    {{ Number(row.schedules[si].penalty_remain) > 0 ? fmt(row.schedules[si].penalty_remain) : '—' }}
                  </td>
                </template>
                <template v-else>
                  <td colspan="7" 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="1" class="fixed-col has-text-weight-bold">TỔNG CỘNG</td>
              <td :colspan="4"></td>

              <!-- Footer TTTHNV -->
              <template v-for="(sch, si) in ttthnvScheduleHeaders" :key="'ttthnv-foot-' + si">
                <td></td>
                <td class="has-text-right has-text-weight-semibold">{{ fmt(ttthnvColSum(si, 'amount')) }}</td>
                <td class="has-text-right has-text-weight-semibold has-text-success">
                  {{ fmt(ttthnvColSum(si, 'paid_amount')) }}
                </td>
                <td></td>
                <td class="has-text-right has-text-weight-semibold has-text-danger">
                  {{ fmt(ttthnvColSum(si, 'amount_remain')) }}
                </td>
                <td class="has-text-right has-text-weight-semibold has-text-danger">
                  {{ fmt(ttthnvColSum(si, 'penalty_remain')) }}
                </td>
              </template>

              <td></td>
              <td></td>

              <!-- Footer HĐCN -->
              <template v-for="(sch, si) in scheduleHeaders" :key="'hd-foot-' + 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>
                <td class="has-text-right has-text-weight-semibold has-text-danger">
                  {{ fmt(colSum(si, 'penalty_remain')) }}
                </td>
              </template>

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

      <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 ttthnvScheduleHeaders = 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 = []
  ttthnvScheduleHeaders.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,penalty_remain,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 ttthnvSchConn = $copy($findapi('payment_schedule'))
    ttthnvSchConn.params = {
      filter: { txn_detail__phase: 4 },
      values: 'id,code,cycle,to_date,from_date,amount,paid_amount,amount_remain,remain_amount,penalty_remain,status,status__name,txn_detail,txn_detail__transaction,txn_detail__phase',
      sort: 'txn_detail__transaction,cycle'
    }

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

    const transactions = txnRs?.data?.rows || []
    const schedules = schRs?.data?.rows || []
    const ttthnvList = ttthnvRs?.data?.rows || []
    const ttthnvSchedules = ttthnvSchRs?.data?.rows || []

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

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

    const schByTxn = {}
    schedules.forEach(s => {
      const tid = s.txn_detail__transaction
      if (!schByTxn[tid]) schByTxn[tid] = []
      schByTxn[tid].push(s)
    })

    const ttthnvSchByTxn = {}
    ttthnvSchedules.forEach(s => {
      const tid = s.txn_detail__transaction
      if (!ttthnvSchByTxn[tid]) ttthnvSchByTxn[tid] = []
      ttthnvSchByTxn[tid].push(s)
    })

    let maxCycles = 0
    Object.values(schByTxn).forEach(list => {
      const n = list.filter(s => Number(s.cycle) > 0).length
      if (n > maxCycles) maxCycles = n
    })

    let maxTtthnvCycles = 0
    Object.values(ttthnvSchByTxn).forEach(list => {
      const n = list.filter(s => Number(s.cycle) > 0).length
      if (n > maxTtthnvCycles) maxTtthnvCycles = n
    })

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

    ttthnvScheduleHeaders.value = Array.from({ length: maxTtthnvCycles }, (_, i) => ({
      label: `TTTHNV thanh toán đợt ${String(i + 1).padStart(2, '0')}`,
      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)
      const luyKe = ttthnvPaid

      let remainingTTTHNV = ttthnvPaid

      const schedulesWithCalc = txnSchedules.map(sch => {
        const scheduleAmount = Number(sch.amount || 0)
        const luyKeSangDot = Math.min(remainingTTTHNV, scheduleAmount)
        const paidAmountFromSchedule = Number(sch.paid_amount || 0)
        const thucThanhToan = Math.max(0, paidAmountFromSchedule - luyKeSangDot)
        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('DD/MM/YYYY') : '—',
          amount: scheduleAmount,
          luy_ke_sang_dot: luyKeSangDot,
          thuc_thanh_toan: thucThanhToan,
          amount_remain: amountRemain,
          penalty_remain: Number(sch.penalty_remain || 0), 
          status: sch.status
        }
      })

      const txnTtthnvSchedules = (ttthnvSchByTxn[txn.id] || [])
        .filter(s => Number(s.cycle) > 0)
        .sort((a, b) => Number(a.cycle) - Number(b.cycle))
        .map(sch => ({
          to_date: sch.to_date ? $dayjs(sch.to_date).format('DD/MM/YYYY') : '—',
          amount: Number(sch.amount || 0),
          paid_amount: Number(sch.paid_amount || 0),
          amount_remain: Number(sch.amount_remain ?? sch.remain_amount ?? 0),
          penalty_remain: Number(sch.penalty_remain || 0) 
        }))

      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)

      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('DD/MM/YYYY') : '—',
        contract_date_raw: txn.date,
        sale_price: salePriceNum,
        ttthnv_paid: ttthnvPaid,
        luy_ke: luyKe,
        schedules: Array.from({ length: maxCycles }, (_, i) => schedulesWithCalc[i] || null),
        ttthnvSchedules: Array.from({ length: maxTtthnvCycles }, (_, i) => txnTtthnvSchedules[i] || null),
        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)
}

function ttthnvColSum(scheduleIndex, field) {
  return filteredRows.value.reduce((sum, row) => {
    const sch = row.ttthnvSchedules[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'
  ]

  ttthnvScheduleHeaders.value.forEach(h => {
    headers.push(
      `${h.label} - Ngày`, `${h.label} - Số tiền`,
      `${h.label} - Đã thanh toán`, `${h.label} - Tỷ lệ`,
      `${h.label} - Dư nợ`, `${h.label} - Lãi phạt`
    )
  })

  headers.push('Tiền nộp TTTHNV', 'Tỷ lệ')

  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ợ`, `${h.label} - Lãi phạt`
    )
  })

  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)]

    ttthnvScheduleHeaders.value.forEach((_, si) => {
      const sch = row.ttthnvSchedules[si]
      if (sch) {
        base.push(
          sch.to_date, fmt(sch.amount), fmt(sch.paid_amount),
          pct(sch.paid_amount, sch.amount), fmt(sch.amount_remain), fmt(sch.penalty_remain)
        )
      } else {
        base.push('', '', '', '', '', '')
      }
    })

    base.push(fmt(row.ttthnv_paid), pct(row.ttthnv_paid, 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), fmt(sch.penalty_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-col {
  position: sticky;
  left: 0;
  z-index: 3;
  background-color: white;
  min-width: 80px;
}
.fixed-col:nth-child(1) { left: 0; min-width: 120px; z-index: 4; }
.fixed-col:nth-child(2) { left: 50px; min-width: 100px; }
.fixed-col:nth-child(3) { left: 150px; min-width: 120px; }
.fixed-col:nth-child(4) { left: 270px; min-width: 110px; }
.fixed-col:nth-child(5) { left: 380px; min-width: 140px; }
.fixed-col:nth-child(6) { left: 520px; min-width: 160px; }
.fixed-col:nth-child(7) { left: 680px; min-width: 160px; }
.fixed-col:nth-child(8) { left: 840px; min-width: 90px; border-right: 2px solid #dee2e6 !important; }
.debt-table thead .fixed-col { position: sticky; top: 0; z-index: 5; background-color: #204853 !important; color: white !important; }
.debt-table tfoot .fixed-col { background-color: #f8f9fa !important; font-weight: bold; }
.debt-table tfoot tr { z-index: 2; }
.fixed-col { box-shadow: 4px 0 5px rgba(0, 0, 0, 0.08); }
</style>