<script setup>
import BaseAlert from "../../../components/base/BaseAlert.vue";
import B2CDataTable from "../../../components/common/B2CDataTable.vue";
import { useAuth } from "../../../composables/useAuth.js";
import { useOffersApi } from "../../offers/composables/useOffersApi.js";
import { computed, onMounted, ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";

const route = useRoute();
const router = useRouter();
const { permissions, user } = useAuth();
const { listOffers } = useOffersApi();

const customerId = computed(() => String(route.params.id ?? ""));

const canViewOffers = computed(() => {
  const mods = user.value?.enabled_module_slugs ?? [];
  return permissions.value.includes("offers.view") && mods.includes("offers");
});

const tableKey = computed(
  () => `customers.show.offers.${customerId.value || "0"}`,
);

const rows = ref([]);
const totalRecords = ref(0);
const loading = ref(false);
const error = ref("");

const pagination = ref({ page: 1, limit: 15 });
const sort = ref([{ field: "updated_at", order: -1 }]);
const tableUiState = ref({
  globalSearch: "",
  filters: {},
});

let loadTimer = null;

const columns = computed(() => [
  {
    key: "offer_number",
    header: "Number",
    type: "text",
    searchable: true,
    filterable: false,
    sortable: true,
  },
  {
    key: "subject",
    header: "Subject",
    type: "text",
    searchable: true,
    filterable: false,
    sortable: true,
  },
  {
    key: "status",
    header: "Status",
    type: "text",
    searchable: false,
    filterable: false,
    sortable: true,
  },
  {
    key: "valid_until",
    header: "Valid until",
    type: "text",
    searchable: false,
    filterable: false,
    sortable: true,
  },
]);

function criteriaSignature(globalSearch, filters) {
  return JSON.stringify({
    globalSearch: String(globalSearch ?? ""),
    filters: filters ?? {},
  });
}

function onTableState(state) {
  const nextGs = String(state?.globalSearch ?? "");
  const nextFilters =
    state?.filters && typeof state.filters === "object"
      ? { ...state.filters }
      : {};

  const prevSig = criteriaSignature(
    tableUiState.value.globalSearch,
    tableUiState.value.filters,
  );
  const nextSig = criteriaSignature(nextGs, nextFilters);

  tableUiState.value = {
    globalSearch: nextGs,
    filters: nextFilters,
  };

  if (nextSig !== prevSig) {
    pagination.value = { ...pagination.value, page: 1 };
    if (loadTimer) clearTimeout(loadTimer);
    loadTimer = setTimeout(() => {
      loadTimer = null;
      load();
    }, 380);
  }
}

function onPagination(p) {
  pagination.value = p;
  load();
}

function onSort(s) {
  sort.value = s;
  load();
}

async function load() {
  if (!canViewOffers.value || !customerId.value) {
    rows.value = [];
    totalRecords.value = 0;
    return;
  }
  loading.value = true;
  error.value = "";
  try {
    const sort0 = sort.value?.[0];
    const sf = sort0?.field ?? "updated_at";
    const asc = Number(sort0?.order) === 1;
    const g = String(tableUiState.value?.globalSearch ?? "").trim();

    const payload = await listOffers({
      customer_id: customerId.value,
      page: pagination.value.page,
      per_page: pagination.value.limit,
      search: g || undefined,
      sort_by: ["offer_number", "subject", "status", "valid_until", "updated_at"].includes(
        sf,
      )
        ? sf
        : "updated_at",
      sort_dir: asc ? "asc" : "desc",
      templates_only: false,
    });

    rows.value = Array.isArray(payload?.data) ? payload.data : [];
    totalRecords.value = payload?.meta?.total ?? rows.value.length;
  } catch {
    error.value = "Could not load offers.";
  } finally {
    loading.value = false;
  }
}

watch([canViewOffers, customerId], () => {
  pagination.value = { ...pagination.value, page: 1 };
  load();
});

onMounted(load);

function openRow(ev) {
  const row = ev?.data ?? ev;
  if (row?.id) {
    router.push(`/offers/${row.id}`);
  }
}
</script>

<template>
  <div>
    <BaseAlert
      v-if="!canViewOffers"
      severity="warn"
      class="mb-4"
      :closable="false"
    >
      Offertes zijn niet beschikbaar (module of rechten ontbreken).
    </BaseAlert>

    <template v-else>
      <BaseAlert v-if="error" severity="warn" class="mb-4" :closable="false">{{
        error
      }}</BaseAlert>

      <B2CDataTable
        :table-key="tableKey"
        :columns="columns"
        :rows="rows"
        :loading="loading"
        server-mode
        :total-records="totalRecords"
        :pagination="pagination"
        :sort="sort"
        :persist-to-server="true"
        search-placeholder="Zoeken…"
        :table-error="error"
        :rows-per-page-options="[10, 15, 25, 50]"
        :rows-per-page="15"
        row-clickable
        @update:pagination="onPagination"
        @update:sort="onSort"
        @update:state="onTableState($event)"
        @row-click="openRow"
      />
    </template>
  </div>
</template>
