<template>
  <div class="report-daily-page mb-4">
    <!-- Report product section -->
    <div class="header-report mb-2">
      <h2 class="header-report-title">Báo cáo tình hình giao dịch & thanh toán theo giai đoạn</h2>
      <div class="select-date">
        <span class="label-date">Từ ngày:</span> &nbsp;
        <Datepicker v-bind="{ record: dateReport, attr: 'date-start' }" @date="select('date-start', $event)" />&nbsp;
        <span class="label-date">đến ngày:</span> &nbsp;
        <Datepicker v-bind="{ record: dateReport, attr: 'date-end' }" @date="select('date-end', $event)" />
      </div>
    </div>

    <div class="body-report">
      <div class="general-report mb-4">
        <!-- Transaction -->
        <div class="general-report-transaction mb-4">
          <h3 class="general-report-title">Giao dịch</h3>
          <div class="grid">
            <div class="cell">
              <div class="card">
                <div class="card-content">
                  <p>Tổng doanh thu</p>
                  <span>{{$numtoString(revenueSummary.salePrice, { hasUnit: true }) }}</span>
                </div>
              </div>
            </div>
            <div class="cell">
              <div class="card">
                <div class="card-content">
                  <p>Đã thu</p>
                  <span>{{$numtoString(revenueSummary.depositAmount, { hasUnit: true }) }}</span>
                </div>
              </div>
            </div>
            <div class="cell">
              <div class="card">
                <div class="card-content">
                  <p>Còn chờ thu</p>
                  <span>{{$numtoString(revenueSummary.salePrice - revenueSummary.depositAmount, { hasUnit: true }) }}</span>
                </div>
              </div>
            </div>
            <div class="cell">
              <div class="card">
                <div class="card-content">
                  <p>Tỉ lệ thu (%)</p>
                  <span
                    :style="{
                      color: ColorStatus(calcPercentage(revenueSummary.depositAmount, revenueSummary.salePrice)),
                    }"
                    >{{ calcPercentage(revenueSummary.depositAmount, revenueSummary.salePrice) }} %</span
                  >
                </div>
              </div>
            </div>
          </div>
        </div>
        <!-- Payment -->
        <div class="general-report-payment mb-4">
          <h3 class="general-report-title">Thanh toán</h3>
          <div class="grid">
            <div class="cell">
              <div class="card">
                <div class="card-content">
                  <p>Tổng tiền phải thu</p>
                  <span>{{$numtoString(paymentStatusSummary.totalPay, { hasUnit: true }) }}</span>
                </div>
              </div>
            </div>
            <div class="cell">
              <div class="card">
                <div class="card-content">
                  <p>Đã thu</p>
                  <span>{{$numtoString(paymentStatusSummary.paid, { hasUnit: true }) }}</span>
                </div>
              </div>
            </div>
            <div class="cell">
              <div class="card">
                <div class="card-content">
                  <p>Còn phải thu</p>
                  <span>{{$numtoString(paymentStatusSummary.unpaid, { hasUnit: true }) }}</span>
                </div>
              </div>
            </div>
            <div class="cell">
              <div class="card">
                <div class="card-content">
                  <p>Tỉ lệ hoàn thành (%)</p>
                  <span
                    :style="{
                      color: ColorStatus(calcPercentage(paymentStatusSummary.paid, paymentStatusSummary.totalPay)),
                    }"
                    >{{ calcPercentage(paymentStatusSummary.paid, paymentStatusSummary.totalPay) }} %</span
                  >
                </div>
              </div>
            </div>
          </div>
        </div>
        <!-- Due -->
        <div class="general-report-due">
          <h3 class="general-report-title">Đến hạn</h3>
          <div class="grid">
            <div class="cell">
              <div class="card">
                <div class="card-content">
                  <p>Giao dịch đến hạn</p>
                  <span>{{ totalTransactionDue }}</span>
                </div>
              </div>
            </div>
            <div class="cell">
              <div class="card">
                <div class="card-content">
                  <p>Doanh thu từ giao dịch đến hạn</p>
                  <span>{{$numtoString(totalAmountTransactionDue, { hasUnit: true }) }}</span>
                </div>
              </div>
            </div>
            <div class="cell">
              <div class="card">
                <div class="card-content">
                  <p>Thanh toán đến hạn</p>
                  <span>{{ totalPaymentDue }}</span>
                </div>
              </div>
            </div>
            <div class="cell">
              <div class="card">
                <div class="card-content">
                  <p>Doanh thu thanh toán đến hạn</p>
                  <span>{{$numtoString(totalAmountPaymentDue, { hasUnit: true }) }}</span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <div class="report report-transaction">
        <h3>Giao dịch</h3>
        <div class="report-transaction-new">
          <div class="grid">
            <div
              class="cell"
              v-for="item in dataTransactionType"
              :key="item.code"
              @click="handlerTransaction($event, item)"
            >
              <div class="card">
                <div class="card-content">
                  <p>{{ item.name }}</p>
                  <span>{{ item.count | 0 }}</span>
                </div>
              </div>
            </div>
          </div>
          <div class="chart">
            <client-only v-if="hasTransactionDataNews">
              <highcharts-vue-chart :highcharts="Highcharts" :options="chartTransactionOptions" />
            </client-only>
            <p v-else class="message-alter">{{ emptyMessageTransactionNews }}</p>
          </div>
        </div>
        <!-- Dealer transactions -->
        <div class="chart dealer-transactions">
          <client-only>
            <highcharts-vue-chart :highcharts="Highcharts" :options="chartDealerTransactionOptions" />
          </client-only>
        </div>
      </div>

      <div class="report report-payment">
        <h3>Thanh toán</h3>
        <div class="report-payment-new">
          <div class="grid">
            <div
              class="cell"
              v-for="item in paymentTypeStatus"
              :key="item.code"
              @click="handlerPaymentSelect($event, item)"
            >
              <div class="card">
                <div class="card-content">
                  <p>{{ item.name }}</p>
                  <span>{{ item.count | 0 }}</span>
                </div>
              </div>
            </div>
          </div>
          <div class="chart">
            <client-only v-if="hasPaymentDataNews">
              <highcharts-vue-chart :highcharts="Highcharts" :options="chartPaymentOptions" />
            </client-only>
            <p v-else class="message-alter">{{ emptyMessagePayMentNews }}</p>
          </div>
        </div>
      </div>
    </div>
    <!-- Popup -->
    <div :class="['modal', { 'is-active': showPopup }]">
      <div class="modal-background" @click="handlerClosePopup"></div>

      <div class="modal-card">
        <header class="modal-card-head my-0 py-2" v-if="titlePopup">
          <div class="w-full">
            <div class="field is-grouped">
              <div class="control is-expanded has-text-left">
                <p class="fsb-18 has-text-primary" v-html="titlePopup"></p>
              </div>
              <div class="control has-text-right">
                <button class="delete is-medium" @click="handlerClosePopup"></button>
              </div>
            </div>
          </div>
        </header>
        <div class="modal-card-body px-4 py-4">Load data danh sách sản phẩm theo trạng thái</div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from "vue";
import Highcharts from "highcharts";
import { Chart as HighchartsVueChart } from "highcharts-vue";

import Datepicker from "~/components/datepicker/Datepicker";

const { $numtoString, $findapi, $getapi, $store, $getdata, $mode } = useNuxtApp();

const dealer = $store.dealer;
const isVietnamese = computed(() => $store.lang.toLowerCase() === "vi");

const today = new Date().toISOString().split("T")[0];

const productsResponse = ref(null);
const transactionResponse = ref(null);
const transactionDueResponse = ref(null);
const paymentResponse = ref(null);
const paymentDueResponse = ref(null);

const showPopup = ref(false);
const dateReport = ref({
  "date-start": today,
  "date-end": today,
});

const labelProductByStatus = ref(null);
const labelTransactionPhase = ref(null);
const productByStatus = ref(null);
const dataTransactionSelect = ref(null);
const dataPaymentSelect = ref(null);
const labelPaymentType = ref(null);
const selectedProductByStatus = null;

const totalProduct = ref(0);
const totalTransactionNews = ref(0);
const totalTransactionDue = ref(0);
const totalPaymentNews = ref(0);
const totalPaymentDue = ref(0);
const listDealer = ref(null);

const formatVniDate = (date) => {
  const dateTemp = date ? new Date(date) : new Date();
  const d = String(dateTemp.getDate()).padStart(2, "0");
  const m = String(dateTemp.getMonth() + 1).padStart(2, "0");
  const y = dateTemp.getFullYear();
  return `${d}/${m}/${y}`;
};

let scrollPosition = 0;

const select = (fieldName, value) => {
  dateReport.value[fieldName] = value;
};

const listTransactionPhase = await $getdata("transactionphase");
const listSalePolicy = await $getdata("salepolicy");
const listPaymentStatus = await $getdata("paymentstatus");
const listPaymentType = await $getdata("paymenttype");
if (!dealer?.code) {
  listDealer.value = await $getdata("dealer");
}
const groupByField = (list, { keyField, nameField, nameTransform, colorField }) => {
  if (!Array.isArray(list) || list.length === 0) return [];

  const map = new Map();

  for (const item of list) {
    const key = item[keyField];
    if (!key) continue;

    let group = map.get(key);

    if (!group) {
      group = {
        key,
        name: nameTransform ? nameTransform(item[nameField]) : nameField ? item[nameField] : key,
        color: colorField ? item[colorField] : null,
        count: 0,
        children: [],
      };
      map.set(key, group);
    }

    group.count++;
    group.children.push(item);
  }

  return [...map.values()];
};

const chartSelectedHandler = ({ source, labelRef, itemRef, selectRef }) => ({
  select() {
    selectRef = this;
    const item = source.value.find((i) => i.key === this.options.key);
    labelRef.value = item?.name ?? null;
    itemRef.value = item?.children ? [...item.children] : [];
    toggleBodyScroll(true);
  },

  unselect() {
    if (selectRef !== this) return;
    selectRef = null;
    labelRef.value = null;
    itemRef.value = [];
    toggleBodyScroll(false);
  },
});

const toggleBodyScroll = (isActive) => {
  if (isActive) {
    scrollPosition = window.scrollY || document.documentElement.scrollTop;
    document.body.classList.add("popup-open");
    document.body.style.top = `-${scrollPosition}px`;
  } else {
    document.body.classList.remove("popup-open");
    document.body.style.top = "";
    window.scrollTo(0, scrollPosition);
  }
};

function buildDateRange(date) {
  if (!date) return null;
  const dateTemp = new Date(date).toISOString().split("T")[0];
  const start = new Date(`${dateTemp}T00:00:00.000Z`);
  const end = new Date(`${dateTemp}T23:59:59.999Z`);

  return {
    start: start.toISOString(),
    end: end.toISOString(),
  };
}

function buildGroupMap(list = []) {
  if (!Array.isArray(list)) return new Map();

  return new Map(list.filter((item) => item?.key != null).map((item) => [item.key, item]));
}

function mergeMasterWithGroup(masterList = [], groupMap) {
  if (!Array.isArray(masterList)) return [];

  return masterList.map((item) => {
    const found = groupMap.get(item.code);

    return {
      ...item,
      count: found?.count ?? 0,
      children: found?.children ?? [],
    };
  });
}

function buildStatusByParent(parentList = [], statusList = [], keyGroup = "") {
  return parentList.map((parent) => {
    const groupedStatus =
      groupByField(parent.children ?? [], {
        keyField: keyGroup,
      }) || [];

    const statusMap = buildGroupMap(groupedStatus);

    const status = statusList.map((st) => {
      const found = statusMap.get(st.code);

      return {
        ...st,
        count: found?.count ?? 0,
        children: found?.children ?? [],
      };
    });

    return {
      ...parent,
      status,
    };
  });
}

function buildChartSeriesByStatus(statusList = [], parentWithStatus = []) {
  return statusList.map((status) => ({
    name: status.name?.split(". ")[1] ?? status.name,
    data: parentWithStatus.map((parent) => {
      const map = new Map((parent.status ?? []).map((st) => [st.code, st.count]));

      return map.get(status.code) ?? 0;
    }),
  }));
}

function calcPercentage(part, whole, decimals = 2) {
  const numerator = Number(part) || 0;
  const denominator = Number(whole) || 0;

  if (denominator === 0) return 0;

  return Number(((numerator / denominator) * 100).toFixed(decimals));
}

function hasData(data) {
  return Array.isArray(data) && data.length > 0;
}

function ColorStatus(value) {
  if (value > 100) {
    return "#006400";
  }

  if (value >= 90 && value <= 100) {
    return "#2ECC71";
  }

  if (value >= 75 && value < 90) {
    return "#F1C40F";
  }

  if (value >= 60 && value < 75) {
    return "#E67E22";
  }

  if (value < 60) {
    return "#E74C3C";
  }

  return "#BDC3C7";
}

const titlePopup = computed(() => {
  const isVi = isVietnamese;
  const productLen = productByStatus?.value?.length;
  const transactionLen = dataTransactionSelect?.value?.length;
  const paymentLen = dataPaymentSelect?.value?.length;
  const dateStart = dateReport.value?.["date-start"];
  const dateEnd = dateReport.value?.["date-end"];
  const dateTextStart = dateStart ? formatVniDate(dateStart) : "";
  const dateTextEnd = dateEnd ? formatVniDate(dateEnd) : "";

  if (productLen) {
    return isVi
      ? `Danh sách sản phẩm - Trạng thái: ${labelProductByStatus.value}`
      : `Product List - Status: ${labelProductByStatus.value}`;
  }

  if (transactionLen) {
    return isVi
      ? `Danh sách giao dịch - Trạng thái: ${labelTransactionPhase.value} (${dateTextStart} - ${dateTextEnd})`
      : `Transaction list - Status: ${labelTransactionPhase.value} (${dateTextStart} - ${dateTextEnd})`;
  }

  if (paymentLen) {
    return isVi
      ? `Danh sách thanh toán - Loại thanh toán: ${labelPaymentType.value} (${dateTextStart} - ${dateTextEnd})`
      : `Payment list - Payment type: ${labelPaymentType.value} (${dateTextStart} - ${dateTextEnd})`;
  }

  return "";
});

// Fetch products data
let foundProduct = $findapi("product");
foundProduct.params.values =
  "id,code,trade_code,zone_code,type__code,type__name,zone_type__code,zone_type__code,zone_type__name,direction__code,direction__name,cart__code,cart__name,cart__dealer__code,cart__dealer__name,origin_price,status__code,status__name,status__color,status__sale_status__code,status__sale_status__name,status__sale_status__color";
if (dealer?.code) {
  foundProduct.params.filter = { cart__dealer__code: dealer?.code };
  foundProduct.params.exclude = { status__sale_status__code: "not-sold" };
}

async function fetchApiProduct() {
  try {
    const [productRes] = await $getapi([foundProduct]);
    productsResponse.value = productRes?.data?.rows ?? [];
    totalProduct.value = productsResponse.value?.length;
  } catch (error) {
    if ($mode === "dev") {
      console.error("Call api product error", error);
    }
    productsResponse.value = [];
    totalProduct.value = 0;
  }
}
fetchApiProduct();

const hasProducts = computed(() => hasData(productsResponse.value));

const emptyMessageProducts = computed(() => (isVietnamese ? `Hiện chưa có sản phẩm` : `No product`));

// Chart product by status
const productStatus = computed(() =>
  groupByField(productsResponse.value, {
    keyField: "status__sale_status__code",
    nameField: "status__sale_status__name",
    nameTransform: (name) => name?.split(". ")[1] ?? name,
    colorField: "status__sale_status__color",
  })
);

const chartProductStatusOptions = computed(() => {
  return {
    chart: {
      type: "pie",
      zooming: {
        type: "xy",
      },
      panning: {
        enabled: true,
        type: "xy",
      },
    },
    title: {
      text: isVietnamese ? "Trạng thái sản phẩm" : "Product status",
    },
    subtitle: {
      text: `(${totalProduct.value} ${isVietnamese ? "Sản phẩm" : "Products"})`,
    },
    plotOptions: {
      pie: {
        allowPointSelect: true,
        cursor: "pointer",
        point: {
          events: chartSelectedHandler({
            source: productStatus,
            labelRef: labelProductByStatus,
            itemRef: productByStatus,
            selectRef: selectedProductByStatus,
          }),
        },
      },
    },

    series: [
      {
        name: isVietnamese ? "Số lượng" : "Quantity",
        colorByPoint: true,
        data: productStatus.value.map((item) => {
          return {
            name: item.name,
            y: item.count,
            key: item.key,
            color: item.color,
          };
        }),
      },
    ],
  };
});

watch(
  productByStatus,
  (newVal) => {
    showPopup.value = Array.isArray(newVal) ? newVal.length > 0 : !!newVal;
  },
  { deep: true }
);
// <-- End Chart product by status -->

// Fetch transactions data
let foundTransaction = $findapi("reservation");
foundTransaction.params.values =
  "id,code,transaction__code,transaction__product__trade_code,transaction__product__zone_code,transaction__customer__code,transaction__customer__fullname,transaction__policy__code,transaction__policy__name,phase,phase__code,phase__name,transaction__product__cart__code,transaction__product__cart__name,transaction__product__cart__dealer,transaction__product__cart__dealer__code,transaction__product__cart__dealer__name,transaction__origin_price,transaction__discount_amount,transaction__sale_price,transaction__deposit_amount,status,status__code,status__name,create_time";

foundTransaction.params.filter = {
  ...(dealer?.code
    ? {
        transaction__product__cart__dealer__code: dealer?.code,
      }
    : {}),
  create_time__gte: buildDateRange(dateReport.value["date-start"])?.start,
  create_time__lte: buildDateRange(dateReport.value["date-end"])?.end,
};

let foundTransactionDue = $findapi("reservation");
foundTransactionDue.params.values =
  "id,code,due_date,transaction__code,transaction__product__trade_code,transaction__product__zone_code,transaction__customer__code,transaction__customer__fullname,transaction__policy__code,transaction__policy__name,phase,phase__code,phase__name,transaction__product__cart__code,transaction__product__cart__name,transaction__product__cart__dealer,transaction__product__cart__dealer__code,transaction__product__cart__dealer__name,transaction__origin_price,transaction__discount_amount,transaction__sale_price,transaction__deposit_amount,status,status__code,status__name,create_time";

foundTransactionDue.params.filter = {
  ...(dealer?.code
    ? {
        transaction__product__cart__dealer__code: dealer?.code,
      }
    : {}),
  due_date__gte: dateReport.value["date-start"],
  due_date__lte: dateReport.value["date-end"],
};
foundTransactionDue.params.exclude = { status__code__in: ["approved", "reject", "cancel"] };

async function fetchApiTransaction() {
  try {
    const [transactionRes, transactionDueRes] = await $getapi([foundTransaction, foundTransactionDue]);

    const transactions = transactionRes?.data?.rows ?? [];
    const dueTransactions = transactionDueRes?.data?.rows ?? [];

    transactionResponse.value = transactions;
    totalTransactionNews.value = transactions.length;

    transactionDueResponse.value = dueTransactions;
    totalTransactionDue.value = dueTransactions.length;
  } catch (error) {
    if ($mode === "dev") {
      console.error("Call api product error", error);
    }
    transactionResponse.value = [];
    totalTransactionNews.value = 0;

    transactionDueResponse.value = [];
    totalTransactionDue.value = 0;
  }
}

fetchApiTransaction();
// <-- End Fetch transactions data -->

const transactionType = computed(() =>
  groupByField(transactionResponse.value || [], {
    keyField: "phase__code",
    nameField: "phase__name",
    nameTransform: (name) => name?.split(". ")[1] ?? name,
  })
);

const revenueSummary = computed(() => {
  const list = transactionResponse.value;
  if (!Array.isArray(list) || list.length === 0) {
    return {
      originPrice: 0,
      discountAmount: 0,
      salePrice: 0,
      depositAmount: 0,
    };
  }

  return list.reduce(
    (acc, item) => {
      acc.originPrice += Number(item.transaction__origin_price) || 0;
      acc.discountAmount += Number(item.transaction__discount_amount) || 0;
      acc.salePrice += Number(item.transaction__sale_price) || 0;
      acc.depositAmount += Number(item.transaction__deposit_amount) || 0;
      return acc;
    },
    {
      originPrice: 0,
      discountAmount: 0,
      salePrice: 0,
      depositAmount: 0,
    }
  );
});

const transactionTypeGroupMap = computed(() => buildGroupMap(transactionType.value));

const dataTransactionType = computed(() => mergeMasterWithGroup(listTransactionPhase, transactionTypeGroupMap.value));

const transactionTypePolicy = computed(() =>
  buildStatusByParent(transactionType.value, listSalePolicy, "transaction__policy__code")
);

const dataChartTransactionPolicy = computed(() =>
  buildChartSeriesByStatus(listSalePolicy, transactionTypePolicy.value)
);

const chartTransactionOptions = computed(() => {
  return {
    chart: {
      type: "column",
    },
    title: {
      text: `${
        isVietnamese ? "Giao dịch phát sinh giai đoạn" : "Transactions occur during this period."
      } ${formatVniDate(dateReport.value?.["date-start"])} - ${formatVniDate(dateReport.value?.["date-end"])}`,
    },

    subtitle: {
      text: `${totalTransactionNews.value} ${isVietnamese ? "Giao dịch" : "Transaction"}`,
    },

    xAxis: {
      categories: dataTransactionType?.value.map((item) => item.name),
      crosshair: true,
      accessibility: {
        description: isVietnamese ? "Giao đoạn giao dịch" : "Trading phase",
      },
    },
    yAxis: {
      min: 0,
      title: {
        text: isVietnamese ? "Số lượng giao dịch" : "Number of transactions",
      },
    },
    tooltip: {
      valueSuffix: isVietnamese ? " (Giao dịch)" : " (Transaction)",
    },

    plotOptions: {
      column: {
        pointPadding: 0.2,
        borderWidth: 0,
      },
    },

    series: dataChartTransactionPolicy.value,
  };
});

const hasTransactionDataNews = computed(() => hasData(transactionResponse.value));

const emptyMessageTransactionNews = computed(() =>
  isVietnamese
    ? `Hiện chưa có giao dịch phát sinh giai đoạn ${formatVniDate(dateReport.value["date-start"])} - ${formatVniDate(
        dateReport.value["date-end"]
      )}`
    : `No transactions phase ${formatVniDate(dateReport.value["date-start"])} - ${formatVniDate(
        dateReport.value["date-end"]
      )}`
);

const handlerTransaction = (e, data) => {
  e.preventDefault();
  e.stopPropagation();
  toggleBodyScroll(true);

  showPopup.value = true;
  dataTransactionSelect.value = data.children ?? [];
  labelTransactionPhase.value = data.name ?? "";
};
// Dealer Transaction

const transactionDealer = computed(() => {
  if (dealer?.code) return [];

  const test =  groupByField(transactionResponse.value || [], {
    keyField: "transaction__product__cart__dealer__code",
    nameField: "transaction__product__cart__dealer__name",
    nameTransform: (name) => name?.split(". ")[1] ?? name,
  });

  console.log('transactionDealer==================' ,test);
  return test
  
});

const transactionDealerGroupMap = computed(() => buildGroupMap(transactionDealer.value));

const dataTransactionDealer = computed(() => {
  if (dealer?.code) return [];

  const test = mergeMasterWithGroup(listDealer.value || [], transactionDealerGroupMap.value);
  console.log('test' , test);
  return test
});

const chartDealerTransactionOptions = computed(() => {
  return {
    chart: {
      type: "column",
    },
    title: {
      text: `${
        isVietnamese
          ? "Giao dịch phát sinh theo đại lý trong giai đoạn"
          : "Transactions are generated through phased agency"
      } ${formatVniDate(dateReport.value?.["date-start"])} - ${formatVniDate(dateReport.value?.["date-end"])}`,
    },

    subtitle: {
      text: `${totalTransactionNews.value} ${isVietnamese ? "Giao dịch" : "Transaction"}`,
    },

    xAxis: {
      categories: listDealer.value?.map((d) => d.code),
    },
    yAxis: {
      min: 0,
      title: {
        text: isVietnamese ? "Phần trăm (%)" : "Percent (%)",
      },
    },
    tooltip: {
      pointFormat:
        '<span style="color:{series.color}">{series.name}</span>' + ": <b>{point.y}</b> ({point.percentage:.0f}%)<br/>",
      shared: true,
    },
    plotOptions: {
      column: {
        stacking: "percent",
        dataLabels: {
          enabled: true,
          format: "{point.percentage:.0f}%",
        },
      },
    },
    series: [
      {
        name: "Đặt cọc",
        data: [434, 290, 307, 0, 0],
      },
      {
        name: "Giữ chỗ",
        data: [272, 153, 156, 0, 0],
      },
      {
        name: "Thỏa thuận THNV",
        data: [13, 7, 8, 1, 0],
      },
      {
        name: "Chuyển nhượng QSDĐ",
        data: [55, 35, 41, 6, 0],
      },
    ],
  };
});

// Transaction Due

const totalAmountTransactionDue = computed(() => {
  return transactionDueResponse.value?.reduce((total, txn) => {
    const salePrice = Number(txn.transaction__sale_price) || 0;
    const deposit = Number(txn.transaction__deposit_amount) || 0;
    return total + (salePrice - deposit);
  }, 0);
});
// <-- End Transaction Due -->

// fetch data payment

let foundPayment = $findapi("payment_schedule");
foundPayment.params.values =
  "id,code,from_date,to_date,type,type__code,type__name,amount,paid_amount,remain_amount,cycle,cycle_days,detail,status,status__code,status__name,txn_detail__code,txn_detail__phase,txn_detail__phase__code,txn_detail__phase__name,txn_detail__transaction__product__trade_code,txn_detail__transaction__product__cart__dealer__code,txn_detail__transaction__product__cart__dealer__name,txn_detail__transaction__customer__code,txn_detail__transaction__customer__fullname,txn_detail__transaction__customer__code,txn_detail__transaction__customer__phone,create_time";
foundPayment.params.filter = {
  ...(dealer?.code
    ? {
        txn_detail__transaction__product__cart__dealer__code: dealer?.code || null,
      }
    : {}),
  create_time__gte: buildDateRange(dateReport.value["date-start"])?.start,
  create_time__lte: buildDateRange(dateReport.value["date-end"])?.end,
};

let foundPaymentDue = $findapi("payment_schedule");
foundPaymentDue.params.values =
  "id,code,from_date,to_date,type,type__code,type__name,amount,paid_amount,remain_amount,cycle,cycle_days,detail,status,status__code,status__name,txn_detail__code,txn_detail__phase,txn_detail__phase__code,txn_detail__phase__name,txn_detail__transaction__product__trade_code,txn_detail__transaction__product__cart__dealer__code,txn_detail__transaction__product__cart__dealer__name,txn_detail__transaction__customer__code,txn_detail__transaction__customer__fullname,txn_detail__transaction__customer__code,txn_detail__transaction__customer__phone,create_time";
foundPaymentDue.params.filter = {
  ...(dealer?.code
    ? {
        txn_detail__transaction__product__cart__dealer__code: dealer?.code || null,
      }
    : {}),
  to_date__gte: dateReport.value["date-start"],
  to_date__lte: dateReport.value["date-end"],
  status__code: "unpaid",
};

async function fetchApiPayment() {
  try {
    const [paymentRes, paymentDueRes] = await $getapi([foundPayment, foundPaymentDue]);
    const payments = paymentRes?.data?.rows ?? [];
    const duePayments = paymentDueRes?.data?.rows ?? [];

    paymentResponse.value = payments;
    totalPaymentNews.value = payments.length;

    paymentDueResponse.value = duePayments;
    totalPaymentDue.value = duePayments.length;
  } catch (error) {
    if ($mode === "dev") {
      console.error("Call api product error", error);
    }
    paymentResponse.value = [];
    totalPaymentNews.value = 0;

    paymentDueResponse.value = [];
    totalPaymentDue.value = 0;
  }
}

fetchApiPayment();

const paymentTypeGroup = computed(() =>
  groupByField(paymentResponse.value || [], {
    keyField: "type__code",
    nameField: "type__name",
    nameTransform: (name) => name?.split(". ")[1] ?? name,
  })
);

const paymentTypeGroupMap = computed(() => buildGroupMap(paymentTypeGroup.value));

const dataPaymentType = computed(() => mergeMasterWithGroup(listPaymentType, paymentTypeGroupMap.value));

const paymentTypeStatus = computed(() => buildStatusByParent(dataPaymentType.value, listPaymentStatus, "status__code"));

const dataChartPaymentStatus = computed(() => buildChartSeriesByStatus(listPaymentStatus, paymentTypeStatus.value));

const chartPaymentOptions = computed(() => {
  return {
    chart: {
      type: "column",
    },
    title: {
      text: `${isVietnamese ? "Thanh toán phát giai đoạn" : "Payment due in stages"} ${formatVniDate(
        dateReport.value?.["date-start"]
      )} - ${formatVniDate(dateReport.value?.["date-end"])}`,
    },

    subtitle: {
      text: `${totalPaymentNews.value || 0} ${isVietnamese ? "Thanh toán" : "Payment"}`,
    },

    xAxis: {
      categories: listPaymentType?.map((item) => item.name),
      crosshair: true,
      accessibility: {
        description: isVietnamese ? "Loại thanh toán" : "Payment type",
      },
    },
    yAxis: {
      min: 0,
      title: {
        text: isVietnamese ? "Số lượng giao dịch" : "Number of transactions",
      },
    },
    tooltip: {
      valueSuffix: isVietnamese ? " (Giao dịch)" : " (Transaction)",
    },

    plotOptions: {
      column: {
        pointPadding: 0.2,
        borderWidth: 0,
      },
    },

    series: dataChartPaymentStatus.value,
  };
});

const hasPaymentDataNews = computed(() => hasData(paymentResponse.value));

const emptyMessagePayMentNews = computed(() =>
  isVietnamese
    ? `Hiện chưa có thanh toán phát sinh giai đoạn ${formatVniDate(dateReport.value["date-start"])} - ${formatVniDate(
        dateReport.value["date-end"]
      )}`
    : `No payments incurred during this period ${formatVniDate(dateReport.value["date-start"])} - ${formatVniDate(
        dateReport.value["date-end"]
      )}`
);

const paymentStatusSummary = computed(() => {
  const payments = Array.isArray(paymentResponse.value) ? paymentResponse.value : [];

  const groupedByStatus = groupByField(payments, {
    keyField: "status__code",
    nameField: "status__name",
    nameTransform: (name) => name?.split(". ")?.[1] ?? name,
  });

  const statusList = groupedByStatus.map((group) => {
    const totalAmount = group.children.reduce((sum, payment) => sum + (Number(payment.amount) || 0), 0);
    return {
      key: group.key ?? "UNKNOWN",
      name: group.name ?? "Không xác định",
      totalAmount,
    };
  });
  return statusList.reduce(
    (acc, item) => {
      acc.totalPay += item.totalAmount;

      if (item.key === "paid") {
        acc.paid += item.totalAmount;
      } else {
        acc.unpaid += item.totalAmount;
      }

      return acc;
    },
    {
      totalPay: 0,
      paid: 0,
      unpaid: 0,
    }
  );
});

const handlerPaymentSelect = (e, data) => {
  e.preventDefault();
  e.stopPropagation();
  toggleBodyScroll(true);
  showPopup.value = true;
  dataPaymentSelect.value = data.children ?? [];
  labelPaymentType.value = data.name ?? "";
};

const totalAmountPaymentDue = computed(() => {
  return paymentDueResponse.value?.reduce((total, mpt) => {
    const amount = Number(mpt.amount) || 0;
    return total + amount;
  }, 0);
});
// <<<<<<<<<<<<<<<<<<<==========================================>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Handler for popup report
const handlerClosePopup = (e) => {
  e.preventDefault();
  e.stopPropagation();

  // Close popup
  showPopup.value = false;

  // Clear data
  productByStatus.value = null;
  dataTransactionSelect.value = null;

  handleUnSelectChart();
  toggleBodyScroll(false);
};

// <-- End Handler for popup report -->

const handleUnSelectChart = () => {
  const chart = Highcharts.charts.find((c) => c);
  if (chart) {
    chart.series[0]?.points.forEach((p) => {
      if (p.selected) p.select(false, false);
    });
  }
};
// Close popup on ESC key
const onEsc = (e) => {
  if (e.key === "Escape") {
    handlerClosePopup(e);
    handleUnSelectChart();
  }
};

onMounted(() => {
  window.addEventListener("keydown", onEsc);
});

onBeforeUnmount(() => {
  window.removeEventListener("keydown", onEsc);
});

// <-- End Close popup on ESC key -->

watch(
  dateReport,
  (newVal) => {
    foundTransaction.params.filter.create_time__gte = buildDateRange(newVal["date-start"])?.start;
    foundTransaction.params.filter.create_time__lte = buildDateRange(newVal["date-end"])?.end;
    foundTransactionDue.params.filter.due_date__gte = dateReport.value["date-start"];
    foundTransactionDue.params.filter.due_date__lte = dateReport.value["date-end"];
    fetchApiTransaction();

    foundPayment.params.filter.create_time__gte = buildDateRange(newVal["date-start"])?.start;
    foundPayment.params.filter.create_time__lte = buildDateRange(newVal["date-start"])?.end;
    foundPaymentDue.params.filter.to_date__gte = dateReport.value["date-start"];
    foundPaymentDue.params.filter.to_date__lte = dateReport.value["date-end"];

    fetchApiPayment();

    console.log("=====> dataTransactionDealer", transactionResponse.value);
  },
  { deep: true }
);
</script>

<style>
body.popup-open {
  position: fixed;
  width: 100%;
  overflow: hidden;
}

.report-daily-page .modal-background {
  opacity: 0.7 !important;
}

.report-daily-page .modal-card {
  width: 90%;
}

.report-daily-page .message-alter {
  text-align: center;
  font-weight: bolder;
  font-style: italic;
}

.report-daily-page .header-report .header-report-title {
  font-size: 2rem;
  font-weight: bolder;
  text-align: center;
  text-transform: uppercase;
}

.report-daily-page .header-report .select-date {
  padding: 10px;
  /* background-color: #f5f5f5; */
  width: max-content;
  border-radius: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto;
}

.report-daily-page .header-report .select-date .label-date {
  font-weight: bolder;
}

.report-daily-page .report-transaction .card,
.report-daily-page .report-payment .card {
  cursor: pointer;
}

/* Container menu */
.report-daily-page .highcharts-contextmenu {
  background: #ffffff !important;
  border-radius: 8px !important;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12) !important;
  padding: 6px 0 !important;
  min-width: 180px;
  z-index: 9999 !important;
}

/* Item menu */
.report-daily-page .highcharts-contextmenu li {
  padding: 10px 16px !important;
  font-size: 14px;
  color: #333;
  cursor: pointer;
  transition: all 0.2s ease;
}

/* Hover */
.report-daily-page .highcharts-contextmenu li:hover {
  background: #f5f7fa !important;
  color: #1e80ff;
}

/* Separator */
.report-daily-page .highcharts-contextmenu hr {
  margin: 6px 0 !important;
  border-color: #eee !important;
}

.report-daily-page .highcharts-data-table table {
  margin: 0 auto;
}

.report-daily-page .highcharts-data-table table th,
.report-daily-page .highcharts-data-table table td {
  padding: 10px;
  border: 1px solid #ddd;
}

.report-daily-page .highcharts-data-table table thead {
  background-color: #204853;
}
.report-daily-page .highcharts-data-table table thead th {
  color: #fff !important;
}
.report-daily-page .highcharts-data-table table tbody tr:nth-child(even) {
  background-color: #f9f9f9;
}
.report-daily-page .highcharts-data-table table tbody tr:hover {
  cursor: pointer;
  background-color: #4a4a4a;
}
.report-daily-page .highcharts-data-table table tbody tr:hover,
.report-daily-page .highcharts-data-table table tbody tr:hover th {
  color: #fff;
}
</style>
