<script setup>
import BaseButton from "../../../components/base/BaseButton.vue";
import BaseIndex from "../../../components/base/BaseIndex.vue";
import B2CDataTable from "../../../components/common/B2CDataTable.vue";
import { useOffersApi } from "../composables/useOffersApi.js";
import { computed, onMounted, ref } from "vue";
import { useRouter } from "vue-router";

import Button from "primevue/button";
import Dialog from "primevue/dialog";
import Message from "primevue/message";
import Select from "primevue/select";

import { useToast } from "primevue/usetoast";

const router = useRouter();
const toast = useToast();

const { listOffers, duplicateFromTemplate, createOffer } = useOffersApi();

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: {},
});

const tplVisible = ref(false);
const tplMenu = ref([]);
const tplPick = ref(null);
const tplBusy = ref(false);

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 onTableState({ pagination: p, sort: s, filters, globalSearch }) {
  if (p) pagination.value = p;
  if (s) sort.value = s;
  if (filters !== undefined) tableUiState.value.filters = filters;
  if (globalSearch !== undefined) tableUiState.value.globalSearch = globalSearch;
  if (loadTimer) clearTimeout(loadTimer);
  loadTimer = setTimeout(() => {
    loadTimer = null;
    load();
  }, 380);
}

async function load() {
  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({
      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;
  }
}

onMounted(load);

async function onNew() {
  try {
    const o = await createOffer({
      subject: "Untitled offer",
      sections: [
        {
          title: "General",
          rows: [
            {
              pricing_type: "one_time",
              quantity: 1,
              unit_price: 0,
              vat_rate: 21,
            },
          ],
        },
      ],
    });
    toast.add({ severity: "success", summary: "Draft created", life: 2000 });
    await router.push(`/offers/${o.id}`);
  } catch {
    toast.add({
      severity: "error",
      summary: "Could not create offer",
      life: 3500,
    });
  }
}

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

async function openTemplateDialog() {
  try {
    const res = await listOffers({ templates_only: true, per_page: 100 });
    tplMenu.value = Array.isArray(res?.data) ? res.data : [];
    tplPick.value = null;
    tplVisible.value = true;
  } catch {
    toast.add({ severity: "error", summary: "Templates unavailable", life: 3000 });
  }
}

async function startFromTemplate() {
  if (!tplPick.value) {
    toast.add({
      severity: "warn",
      summary: "Select a template first",
      life: 2500,
    });
    return;
  }
  tplBusy.value = true;
  try {
    const o = await duplicateFromTemplate({ template_id: tplPick.value.id });
    tplVisible.value = false;
    toast.add({ severity: "success", summary: "Copied from template", life: 2200 });
    await router.push(`/offers/${o.id}`);
  } catch {
    toast.add({ severity: "error", summary: "Duplicate failed", life: 3500 });
  } finally {
    tplBusy.value = false;
  }
}
</script>

<template>
  <BaseIndex title="Offers" subtitle="Quotes and customer-facing proposals.">
    <div class="mb-3 flex flex-wrap items-center gap-2">
      <BaseButton label="New draft" icon="pi pi-plus" severity="primary" @click="onNew" />
      <Button label="Start from template" variant="text" icon="pi pi-copy" type="button" @click="openTemplateDialog" />
    </div>

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

    <B2CDataTable
      table-key="offers.index"
      v-model:data="rows"
      :columns="columns"
      :lazy="false"
      :loading="loading"
      :pagination="pagination"
      :sort="sort"
      :total-records="totalRecords"
      data-key="id"
      removable-sort
      @state-change="onTableState"
      @row-click="openRow"
    />

    <Dialog v-model:visible="tplVisible" header="Start from template" modal class="max-w-lg">
      <div class="flex flex-col gap-3">
        <Select v-model="tplPick" :options="tplMenu" option-label="template_name" placeholder="Pick template" class="w-full" />
        <Button label="Create draft" icon="pi pi-check" :loading="tplBusy" severity="primary" type="button" @click="startFromTemplate" />
      </div>
    </Dialog>
  </BaseIndex>
</template>
