<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 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: () => [] },
  formatEuro: { type: Function, required: true },
  rowTotal: { type: Function, required: true },
  /** Lifts the block visually when a full-page document background is active. */
  elevated: { type: Boolean, default: false },
});

const emit = defineEmits(["dirty"]);

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 removeCategory(ci) {
  if ((props.block.children?.length ?? 0) <= 1) return;
  props.block.children.splice(ci, 1);
  emit("dirty");
}

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: "",
    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("dirty");
}

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

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)
    : String(item.name ?? "");
  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("dirty");
}

const blockTitle = computed({
  get: () => props.block.title ?? "Price indication",
  set: (v) => {
    props.block.title = v;
    emit("dirty");
  },
});

/** Plain-text preview; strips legacy HTML from stored offers. */
function lineDescriptionPreview(val) {
  if (val == null || val === "") {
    return "";
  }
  const s = String(val);
  if (!/<[a-z][\s\S]*>/i.test(s)) {
    return s;
  }
  if (typeof document === "undefined") {
    return s.replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim();
  }
  const el = document.createElement("div");
  el.innerHTML = s;
  return el.textContent || el.innerText || "";
}

function setRowDiscountType(row, type) {
  row.discount_type = type;
  if (type === "none") {
    row.discount_value = 0;
  }
  emit("dirty");
}
</script>

<template>
  <section
    id="offer-pricing"
    class="rounded-2xl border-2 border-amber-300/90 dark:border-amber-700/50 bg-gradient-to-b from-[#fff8e7] via-amber-50/95 to-amber-50/80 dark:from-amber-950/50 dark:via-surface-900 dark:to-surface-950 overflow-hidden scroll-mt-16 shadow-md"
    :class="elevated ? 'ring-1 ring-amber-400/50 dark:ring-amber-600/40 shadow-xl backdrop-blur-sm' : ''"
  >
    <div
      class="flex flex-wrap items-center gap-3 px-6 md:px-8 py-4 border-b border-amber-200/80 dark:border-amber-800/50 bg-amber-100/40 dark:bg-amber-950/40"
    >
      <div class="flex items-center gap-2 text-amber-800 dark:text-amber-200 shrink-0">
        <BaseIcon name="calculator" class="text-lg" />
        <span class="text-xs font-bold uppercase tracking-widest">Prijsindicatie</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-amber-950 dark:text-amber-50 placeholder:text-amber-400"
        placeholder="Prijsindicatie"
      />
    </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 || (block.children?.length ?? 0) <= 1"
        @end="emit('dirty')"
      >
        <template #item="{ element: cat, index: ci }">
          <div class="mb-4 last:mb-0">
            <div
              v-if="(block.children?.length ?? 0) > 1"
              class="w-full flex items-center gap-3 px-3 py-2.5 mb-3 rounded-lg border border-amber-200/80 dark:border-amber-800/60 bg-amber-50/80 dark:bg-amber-950/30"
            >
              <span
                v-if="editable && !preview"
                class="drag-cat cursor-grab text-amber-400 hover:text-amber-600 shrink-0"
                title="Sleep categorie"
              >
                <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="Categorie"
                @update:model-value="emit('dirty')"
              />
              <span v-else class="flex-1 font-semibold text-amber-950 dark:text-amber-100">{{ cat.title }}</span>
              <span class="text-sm tabular-nums font-medium text-amber-900 dark:text-amber-200/90 shrink-0">
                {{ formatEuro(categorySubtotal(cat)) }}
              </span>
              <button
                v-if="editable && !preview && (block.children?.length ?? 0) > 1"
                type="button"
                class="p-1.5 rounded-lg text-amber-300 hover:text-red-600 shrink-0"
                title="Categorie verwijderen"
                @click.stop="removeCategory(ci)"
              >
                <BaseIcon name="trash" class="text-xs" />
              </button>
            </div>

            <BaseDraggable
              v-model="cat.rows"
              item-key="_key"
              handle=".drag-row"
              :disabled="!editable || preview"
              @end="emit('dirty')"
            >
              <template #item="{ element: row, index: ri }">
                <div
                  class="group rounded-xl border-2 border-amber-300/85 dark:border-amber-600/45 bg-[#fff4d1]/95 dark:bg-amber-950/35 overflow-hidden mb-4 last:mb-0 shadow-sm"
                >
                  <div class="p-4 md:p-5 space-y-4">
                    <div class="flex items-start justify-between gap-3">
                      <div class="min-w-0 flex-1 space-y-1">
                        <div
                          v-if="preview"
                          class="text-sm font-medium text-amber-950 dark:text-amber-50 whitespace-pre-wrap min-h-[1.25rem]"
                        >
                          {{ lineDescriptionPreview(row.description_html) || "—" }}
                        </div>
                        <BaseInputText
                          v-else
                          v-model="row.description_html"
                          placeholder="Omschrijving regel"
                          fluid
                          :disabled="!editable"
                          @update:model-value="emit('dirty')"
                        />
                      </div>
                      <div v-if="editable && !preview" class="flex items-center gap-0.5 shrink-0">
                        <button
                          type="button"
                          class="drag-row cursor-grab p-2 text-amber-400 hover:text-amber-700 rounded-md hover:bg-amber-100/80 dark:hover:bg-amber-900/40"
                          title="Sleep regel"
                        >
                          <BaseIcon name="bars" class="text-sm" />
                        </button>
                        <button
                          type="button"
                          class="p-2 text-amber-400 hover:text-red-600 rounded-md hover:bg-red-50 dark:hover:bg-red-950/30"
                          title="Regel verwijderen"
                          @click="removeRow(ci, ri)"
                        >
                          <BaseIcon name="trash" class="text-sm" />
                        </button>
                      </div>
                    </div>

                    <div
                      class="grid grid-cols-1 md:grid-cols-2 gap-6 md:gap-8 pt-2 border-t border-amber-200/70 dark:border-amber-800/50"
                    >
                      <!-- Verkoop -->
                      <div class="space-y-4 min-w-0">
                        <div class="text-sm font-semibold text-amber-600 dark:text-amber-400 tracking-wide">
                          Verkoop
                        </div>
                        <div>
                          <label class="block text-xs font-medium text-amber-800/90 dark:text-amber-200/90 mb-1.5">
                            Aantal
                          </label>
                          <div class="flex flex-wrap items-end gap-2">
                            <BaseInputNumber
                              v-if="!preview"
                              v-model="row.quantity"
                              :use-grouping="false"
                              :min-fraction-digits="2"
                              :max-fraction-digits="2"
                              :disabled="!editable"
                              class="min-w-[6rem] flex-1"
                              @update:model-value="emit('dirty')"
                            />
                            <span v-else class="text-sm tabular-nums font-medium text-amber-950 dark:text-amber-50">{{
                              row.quantity
                            }}</span>
                            <BaseSelect
                              v-if="!preview"
                              v-model="row.pricing_type"
                              :options="pricingOptions"
                              option-label="label"
                              option-value="value"
                              :show-clear="false"
                              :fluid="false"
                              class="min-w-[10rem] max-w-full flex-1"
                              :disabled="!editable"
                              @change="emit('dirty')"
                            />
                          </div>
                        </div>
                        <div>
                          <label class="block text-xs font-medium text-amber-800/90 dark:text-amber-200/90 mb-1.5">
                            Prijs
                          </label>
                          <div class="flex items-center gap-2 rounded-lg border border-amber-300/90 dark:border-amber-700/60 bg-white/90 dark:bg-surface-950/40 px-3 py-1 focus-within:ring-2 focus-within:ring-amber-400/40">
                            <span class="text-amber-700 dark:text-amber-300 font-semibold shrink-0">€</span>
                            <BaseInputNumber
                              v-if="!preview"
                              v-model="row.unit_price"
                              mode="decimal"
                              :use-grouping="false"
                              :max-fraction-digits="2"
                              :disabled="!editable"
                              class="flex-1 min-w-0 border-0 shadow-none [&_.p-inputnumber]:border-0"
                              @update:model-value="emit('dirty')"
                            />
                            <span v-else class="text-sm tabular-nums font-semibold text-amber-950 dark:text-amber-50">{{
                              formatEuro(row.unit_price)
                            }}</span>
                          </div>
                        </div>
                        <div>
                          <label class="block text-xs font-medium text-amber-800/90 dark:text-amber-200/90 mb-1.5">
                            Korting
                          </label>
                          <div class="flex flex-wrap items-center gap-2">
                            <BaseInputNumber
                              v-if="!preview"
                              v-model="row.discount_value"
                              :use-grouping="false"
                              :max-fraction-digits="2"
                              :disabled="!editable || row.discount_type === 'none'"
                              class="min-w-[6rem] flex-1"
                              @update:model-value="emit('dirty')"
                            />
                            <div class="flex rounded-lg border border-amber-400/90 overflow-hidden shrink-0">
                              <button
                                type="button"
                                class="w-10 h-10 text-sm font-bold transition-colors"
                                :class="
                                  row.discount_type === 'percent'
                                    ? 'bg-amber-500 text-white'
                                    : 'bg-white/90 dark:bg-surface-900 text-amber-800 dark:text-amber-200 hover:bg-amber-50 dark:hover:bg-amber-950'
                                "
                                :disabled="!editable || preview"
                                @click="setRowDiscountType(row, 'percent')"
                              >
                                %
                              </button>
                              <button
                                type="button"
                                class="w-10 h-10 text-sm font-bold border-l border-amber-400/90 transition-colors"
                                :class="
                                  row.discount_type === 'fixed'
                                    ? 'bg-amber-500 text-white'
                                    : 'bg-white/90 dark:bg-surface-900 text-amber-800 dark:text-amber-200 hover:bg-amber-50 dark:hover:bg-amber-950'
                                "
                                :disabled="!editable || preview"
                                @click="setRowDiscountType(row, 'fixed')"
                              >
                                €
                              </button>
                            </div>
                          </div>
                        </div>
                        <BaseInputText
                          v-if="!preview && row.pricing_type === 'custom_unit'"
                          v-model="row.custom_unit_label"
                          label="Eenheid label"
                          :disabled="!editable"
                          @update:model-value="emit('dirty')"
                        />
                      </div>

                      <!-- Opties -->
                      <div class="space-y-4 min-w-0">
                        <div class="flex items-center justify-between gap-2">
                          <div class="text-sm font-semibold text-amber-600 dark:text-amber-400 tracking-wide">
                            Opties
                          </div>
                          <BaseButton
                            v-if="editable && !preview"
                            type="button"
                            variant="secondary"
                            text
                            size="small"
                            icon="search"
                            label="Catalogus"
                            class="shrink-0 !text-amber-800 dark:!text-amber-200"
                            @click="openCatalog(ci, ri)"
                          />
                        </div>
                        <div>
                          <label class="block text-xs font-medium text-amber-800/90 dark:text-amber-200/90 mb-1.5">
                            Btw
                          </label>
                          <BaseSelect
                            v-if="!preview"
                            v-model="row.vat_rate"
                            :options="vatOptions"
                            option-label="label"
                            option-value="value"
                            :show-clear="false"
                            :fluid="true"
                            :disabled="!editable"
                            @change="emit('dirty')"
                          />
                          <span v-else class="text-sm text-amber-900 dark:text-amber-100">{{
                            vatOptions.find((o) => o.value === row.vat_rate)?.label ?? `${row.vat_rate}%`
                          }}</span>
                        </div>
                      </div>
                    </div>

                    <div
                      class="flex items-center justify-between gap-3 pt-3 mt-1 border-t border-amber-300/70 dark:border-amber-700/50"
                    >
                      <span class="text-sm font-semibold text-amber-600 dark:text-amber-400 tracking-wide">
                        Totalen
                      </span>
                      <span class="text-base font-bold tabular-nums text-amber-950 dark:text-amber-50">
                        {{ formatEuro(rowTotal(row)) }}
                      </span>
                    </div>
                  </div>
                </div>
              </template>
            </BaseDraggable>

            <div v-if="editable && !preview" class="flex justify-center pt-1">
              <BaseButton
                type="button"
                variant="secondary"
                outlined
                icon="plus"
                label="Regel toevoegen"
                class="!border-2 !border-dashed !border-amber-300 dark:!border-amber-700 !text-amber-900 dark:!text-amber-100"
                @click="addRow(ci)"
              />
            </div>
          </div>
        </template>
      </BaseDraggable>

    </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>
