<script setup>
/**
 * Fixed pricing block: categories with line items (catalog or manual).
 * Mutates the pricing_root section object in place.
 */
import BaseButton from "../../../components/base/BaseButton.vue";
import BaseDraggable from "../../../components/base/BaseDraggable.vue";
import BaseEditor from "../../../components/base/BaseEditor.vue";
import BaseIcon from "../../../components/base/BaseIcon.vue";
import BaseInputNumber from "../../../components/base/BaseInputNumber.vue";
import BaseInputText from "../../../components/base/BaseInputText.vue";
import BaseModal from "../../../components/base/BaseModal.vue";
import BaseSelect from "../../../components/base/BaseSelect.vue";
import { useOffersApi } from "../composables/useOffersApi.js";
import { computed, ref } from "vue";

const props = defineProps({
  /** Root section with section_role === pricing_root */
  block: { type: Object, required: true },
  preview: { type: Boolean, default: false },
  editable: { type: Boolean, default: false },
  vatOptions: { type: Array, default: () => [] },
  pricingOptions: { type: Array, default: () => [] },
  discountOptions: { type: Array, default: () => [] },
  formatEuro: { type: Function, required: true },
  rowTotal: { type: Function, required: true },
});

const emit = defineEmits(["schedule-save"]);

const { listCatalog } = useOffersApi();

const catalogDialog = ref(false);
const catalogRows = ref([]);
const catalogSearch = ref("");
const activePick = ref({ ci: 0, ri: 0 });

function categorySubtotal(cat) {
  return (cat.rows ?? []).reduce((sum, row) => sum + props.rowTotal(row), 0);
}

function addCategory() {
  if (!props.block.children) props.block.children = [];
  const n = (props.block.children?.length ?? 0) + 1;
  props.block.children.push({
    _key: `nc-${crypto.randomUUID()}`,
    title: `Category ${n}`,
    description_html: "",
    section_role: "pricing_category",
    rows: [
      {
        _key: `nr-${crypto.randomUUID()}`,
        description_html: "<p></p>",
        pricing_type: "one_time",
        quantity: 1,
        unit_price: 0,
        discount_type: "none",
        discount_value: 0,
        vat_rate: props.vatOptions?.[0]?.value ?? 21,
        custom_unit_label: "",
      },
    ],
  });
  emit("schedule-save");
}

function removeCategory(ci) {
  if ((props.block.children?.length ?? 0) <= 1) return;
  props.block.children.splice(ci, 1);
  emit("schedule-save");
}

function addRow(ci) {
  const cat = props.block.children?.[ci];
  if (!cat) return;
  if (!cat.rows) cat.rows = [];
  cat.rows.push({
    _key: `nr-${crypto.randomUUID()}`,
    description_html: "<p></p>",
    pricing_type: "one_time",
    quantity: 1,
    unit_price: 0,
    discount_type: "none",
    discount_value: 0,
    vat_rate: props.vatOptions?.[0]?.value ?? 21,
    custom_unit_label: "",
  });
  emit("schedule-save");
}

function removeRow(ci, ri) {
  props.block.children?.[ci]?.rows?.splice(ri, 1);
  emit("schedule-save");
}

async function openCatalog(ci, ri) {
  activePick.value = { ci, ri };
  catalogSearch.value = "";
  await loadCatalog();
  catalogDialog.value = true;
}

async function loadCatalog() {
  const res = await listCatalog({ search: catalogSearch.value || undefined, per_page: 80, include_inactive: false });
  catalogRows.value = res?.data ?? [];
}

function applyCatalogItem(item) {
  const { ci, ri } = activePick.value;
  const row = props.block.children[ci].rows[ri];
  row.description_html = item.default_description?.trim()
    ? String(item.default_description)
    : `<p>${item.name}</p>`;
  row.pricing_type = item.default_pricing_type;
  row.unit_price = item.default_unit_price;
  row.quantity = item.default_quantity;
  row.vat_rate = item.default_vat_rate;
  row.custom_unit_label = item.default_custom_unit_label ?? "";
  row.offer_service_catalog_item_id = item.id;
  catalogDialog.value = false;
  emit("schedule-save");
}

const blockTitle = computed({
  get: () => props.block.title ?? "Price indication",
  set: (v) => {
    props.block.title = v;
    emit("schedule-save");
  },
});
</script>

<template>
  <section
    id="offer-pricing"
    class="rounded-2xl border border-sky-200/80 dark:border-sky-900/40 bg-gradient-to-b from-sky-50/90 to-white dark:from-sky-950/20 dark:to-surface-900 overflow-hidden scroll-mt-16 shadow-sm"
  >
    <!-- Header -->
    <div
      class="flex flex-wrap items-center gap-3 px-6 md:px-8 py-4 border-b border-sky-100 dark:border-sky-900/50 bg-sky-100/50 dark:bg-sky-950/30"
    >
      <div class="flex items-center gap-2 text-sky-800 dark:text-sky-200 shrink-0">
        <i class="pi pi-calculator text-lg" aria-hidden="true" />
        <span class="text-xs font-bold uppercase tracking-widest">Pricing</span>
      </div>
      <input
        v-model="blockTitle"
        :disabled="!editable || preview"
        class="flex-1 min-w-[12rem] text-lg font-semibold bg-transparent border-0 outline-none text-surface-900 dark:text-surface-0"
        placeholder="Price indication"
      />
      <span class="text-xs text-sky-700/70 dark:text-sky-300/70 hidden sm:inline">Fixed block · cannot be removed</span>
    </div>

    <div class="px-4 md:px-6 py-5 flex flex-col gap-4">
      <BaseDraggable
        v-model="block.children"
        item-key="_key"
        handle=".drag-cat"
        :disabled="!editable || preview"
        @end="emit('schedule-save')"
      >
        <template #item="{ element: cat, index: ci }">
          <div
            class="rounded-xl border border-surface-200 dark:border-surface-700 bg-white/90 dark:bg-surface-900/90 overflow-hidden mb-3 shadow-sm"
          >
            <!-- Category bar -->
            <div
              class="w-full flex items-center gap-3 px-4 py-3 text-left bg-slate-50 dark:bg-surface-800/80 border-b border-surface-100 dark:border-surface-700"
            >
              <span
                v-if="editable && !preview"
                class="drag-cat cursor-grab text-surface-300 hover:text-surface-500 shrink-0"
                title="Drag category"
              >
                <BaseIcon name="bars" class="text-sm" />
              </span>
              <BaseInputText
                v-if="!preview"
                v-model="cat.title"
                class="flex-1 min-w-0 !mb-0"
                :disabled="!editable"
                placeholder="Category name"
                @update:model-value="emit('schedule-save')"
              />
              <span v-else class="flex-1 font-semibold text-surface-900 dark:text-surface-0">{{ cat.title }}</span>
              <span class="text-sm tabular-nums font-medium text-surface-600 dark:text-surface-300 shrink-0">
                Subtotal {{ formatEuro(categorySubtotal(cat)) }}
              </span>
              <button
                v-if="editable && !preview && (block.children?.length ?? 0) > 1"
                type="button"
                class="p-1.5 rounded-lg text-surface-300 hover:text-red-500 shrink-0"
                title="Remove category"
                @click.stop="removeCategory(ci)"
              >
                <BaseIcon name="trash" class="text-xs" />
              </button>
            </div>

            <div class="px-3 pb-3 pt-2">
              <div
                class="grid gap-2 text-[11px] font-semibold uppercase tracking-wider text-surface-400 px-2 mb-2"
                :class="editable && !preview ? 'grid-cols-[1fr_5rem_9rem_5rem_8rem_3rem]' : 'grid-cols-[1fr_5rem_9rem_5rem_8rem]'"
              >
                <span>Item</span>
                <span class="text-right">Qty</span>
                <span class="text-right">Unit</span>
                <span class="text-right">VAT</span>
                <span class="text-right">Total</span>
                <span v-if="editable && !preview" />
              </div>

              <BaseDraggable
                v-model="cat.rows"
                item-key="_key"
                handle=".drag-row"
                :disabled="!editable || preview"
                @end="emit('schedule-save')"
              >
                <template #item="{ element: row, index: ri }">
                  <div
                    class="group grid items-start gap-2 px-2 py-3 rounded-lg border border-transparent hover:border-surface-200 dark:hover:border-surface-600 hover:bg-surface-50/80 dark:hover:bg-surface-800/40"
                    :class="editable && !preview ? 'grid-cols-[1fr_5rem_9rem_5rem_8rem_3rem]' : 'grid-cols-[1fr_5rem_9rem_5rem_8rem]'"
                  >
                    <div class="min-w-0">
                      <div
                        v-if="preview"
                        class="prose prose-sm dark:prose-invert max-w-none"
                        v-html="row.description_html"
                      />
                      <BaseEditor
                        v-else
                        v-model="row.description_html"
                        :disabled="!editable"
                        toolbar="document"
                        editor-style="min-height: 72px"
                        @update:model-value="emit('schedule-save')"
                      />
                      <div v-if="!preview && editable" class="flex flex-wrap items-center gap-1.5 mt-1.5">
                        <BaseSelect
                          v-model="row.pricing_type"
                          :options="pricingOptions"
                          option-label="label"
                          option-value="value"
                          :show-clear="false"
                          :fluid="false"
                          class="w-28"
                          :disabled="!editable"
                          @change="emit('schedule-save')"
                        />
                        <button
                          type="button"
                          class="inline-flex items-center gap-1 px-2 py-0.5 text-xs text-primary-600 dark:text-primary-400 hover:bg-primary-50 dark:hover:bg-primary-950/30 rounded-md"
                          @click="openCatalog(ci, ri)"
                        >
                          <i class="pi pi-search text-[10px]" />
                          Catalog
                        </button>
                        <span class="text-surface-300 dark:text-surface-600">·</span>
                        <BaseSelect
                          v-model="row.discount_type"
                          :options="discountOptions"
                          option-label="label"
                          option-value="value"
                          :show-clear="false"
                          :fluid="false"
                          class="w-28"
                          :disabled="!editable"
                          @change="emit('schedule-save')"
                        />
                        <BaseInputNumber
                          v-if="row.discount_type !== 'none'"
                          v-model="row.discount_value"
                          :use-grouping="false"
                          :disabled="!editable"
                          class="w-20"
                          @update:model-value="emit('schedule-save')"
                        />
                        <BaseInputText
                          v-if="row.pricing_type === 'custom_unit'"
                          v-model="row.custom_unit_label"
                          placeholder="Unit label"
                          class="w-24"
                          :disabled="!editable"
                          @update:model-value="emit('schedule-save')"
                        />
                      </div>
                    </div>
                    <div class="text-right">
                      <BaseInputNumber
                        v-if="!preview"
                        v-model="row.quantity"
                        :use-grouping="false"
                        :disabled="!editable"
                        class="w-full"
                        @update:model-value="emit('schedule-save')"
                      />
                      <span v-else class="text-sm tabular-nums">{{ row.quantity }}</span>
                    </div>
                    <div class="text-right">
                      <BaseInputNumber
                        v-if="!preview"
                        v-model="row.unit_price"
                        mode="decimal"
                        :use-grouping="false"
                        :max-fraction-digits="2"
                        :disabled="!editable"
                        class="w-full"
                        @update:model-value="emit('schedule-save')"
                      />
                      <span v-else class="text-sm tabular-nums">{{ formatEuro(row.unit_price) }}</span>
                    </div>
                    <div class="text-right">
                      <BaseSelect
                        v-if="!preview"
                        v-model="row.vat_rate"
                        :options="vatOptions"
                        option-label="label"
                        option-value="value"
                        :show-clear="false"
                        :fluid="false"
                        class="w-full"
                        :disabled="!editable"
                        @change="emit('schedule-save')"
                      />
                      <span v-else class="text-sm text-surface-500">{{ row.vat_rate }}%</span>
                    </div>
                    <div class="text-right pt-1">
                      <span class="text-sm font-semibold tabular-nums">{{ formatEuro(rowTotal(row)) }}</span>
                    </div>
                    <div v-if="editable && !preview" class="flex justify-end gap-0.5 pt-0.5">
                      <button type="button" class="drag-row cursor-grab p-1 text-surface-300 hover:text-surface-500 rounded">
                        <BaseIcon name="bars" class="text-xs" />
                      </button>
                      <button
                        type="button"
                        class="p-1 text-surface-300 hover:text-red-500 rounded"
                        @click="removeRow(ci, ri)"
                      >
                        <BaseIcon name="trash" class="text-xs" />
                      </button>
                    </div>
                  </div>
                </template>
              </BaseDraggable>

              <div v-if="editable && !preview" class="mt-3 flex justify-center">
                <button
                  type="button"
                  class="inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-primary-600 dark:text-primary-400 border border-dashed border-primary-200 dark:border-primary-800 rounded-xl hover:bg-primary-50 dark:hover:bg-primary-950/20"
                  @click="addRow(ci)"
                >
                  <i class="pi pi-plus text-xs" />
                  Add line
                </button>
              </div>
            </div>
          </div>
        </template>
      </BaseDraggable>

      <button
        v-if="editable && !preview"
        type="button"
        class="flex items-center justify-center gap-2 w-full py-3 rounded-xl border-2 border-dashed border-sky-200 dark:border-sky-800 text-sm font-medium text-sky-700 dark:text-sky-300 hover:bg-sky-50 dark:hover:bg-sky-950/30 transition-colors"
        @click="addCategory"
      >
        <i class="pi pi-plus" />
        Add category
      </button>
    </div>

    <BaseModal v-model:visible="catalogDialog" title="Pick from catalog" width="36rem" @show="loadCatalog">
      <div class="flex gap-2 mb-4">
        <BaseInputText v-model="catalogSearch" placeholder="Search…" class="flex-1" @keyup.enter="loadCatalog" />
        <BaseButton label="Search" icon="search" variant="secondary" @click="loadCatalog" />
      </div>
      <div class="max-h-80 overflow-auto flex flex-col gap-0.5">
        <button
          v-for="item in catalogRows"
          :key="item.id"
          type="button"
          class="flex items-start gap-3 w-full text-left px-3 py-2.5 rounded-xl hover:bg-surface-100 dark:hover:bg-surface-800"
          @click="applyCatalogItem(item)"
        >
          <div class="flex-1 min-w-0">
            <div class="font-medium text-sm">{{ item.name }}</div>
            <div v-if="item.default_unit_price" class="text-xs text-surface-500 mt-0.5">
              {{ formatEuro(item.default_unit_price) }} · {{ item.default_pricing_type }}
            </div>
          </div>
        </button>
        <p v-if="!catalogRows.length" class="text-center text-sm text-surface-400 py-8">No catalog items.</p>
      </div>
    </BaseModal>
  </section>
</template>
