---
import Layout from "../../../layouts/Layout.astro";
import ProductCard from "../../../components/ProductCard.astro";
import HeartRating from "../../../components/HeartRating.astro";
import { categories, subcategoryChipLabel } from "../../../data/categories";
import { products, durchschnittsbewertung, anzahlBewertungen } from "../../../data/products";
import type { Locale } from "../../../i18n/config";
import { useTranslations } from "../../../i18n/ui";

const lang: Locale = "fr";
const t = useTranslations(lang);
---
<Layout title="Boutique" description="La boutique complète Van's DIY & Bastelbedarf – crochet, peluches, bijoux et fournitures créatives." lang={lang} path="/shop/">
  <div class="container">
    <section class="page-banner" style="background-image:url('/img/banner-shop.webp'); --banner-ratio: 1600 / 729;">
      <div class="page-banner-content">
        <span class="eyebrow">{t.shop.breadcrumbShop}</span>
        <h1>{t.shop.title}</h1>
        <p class="lead">{t.shop.lead}</p>
      </div>
    </section>
  </div>

  <section class="section-tight">
    <div class="container shop-layout">
      <aside class="filters card" aria-label={t.shop.filters}>
        <h3>{t.shop.filters}</h3>
        <div class="filter-group">
          <span id="f-kategorie-label">{t.shop.categoryLabel}</span>
          <div class="cat-filter" id="cat-filter" data-dropdown>
            <input type="hidden" id="f-kategorie" value="" />
            <button type="button" class="cat-filter-btn" data-dropdown-btn aria-haspopup="listbox" aria-expanded="false" aria-labelledby="f-kategorie-label">
              <span data-dropdown-current>{t.shop.allCategories}</span>
              <span class="chevron" aria-hidden="true">▼</span>
            </button>
            <div class="cat-filter-menu" role="listbox" aria-labelledby="f-kategorie-label">
              <button type="button" class="cat-filter-option" data-value="" data-label={t.shop.allCategories} role="option" aria-selected="true">{t.shop.allCategories}</button>
              {categories.map((c) => (
                c.subcategories && c.subcategories.length > 0 ? (
                  <div class="cat-filter-group">
                    <span class="cat-filter-group-label" aria-hidden="true">{c.icon} {c.name[lang]}</span>
                    <button type="button" class="cat-filter-option" data-value={c.slug} data-label={`${c.icon} ${c.name[lang]}`} role="option" aria-selected="false">{t.shop.allCategories} – {c.name[lang]}</button>
                    {c.subcategories.map((s) => (
                      <button type="button" class="cat-filter-option cat-filter-sub" data-value={`sub:${s.slug}`} data-label={subcategoryChipLabel(s, lang)} role="option" aria-selected="false">{subcategoryChipLabel(s, lang)}</button>
                    ))}
                  </div>
                ) : (
                  <button type="button" class="cat-filter-option" data-value={c.slug} data-label={`${c.icon} ${c.name[lang]}`} role="option" aria-selected="false">{c.icon} {c.name[lang]}</button>
                )
              ))}
            </div>
          </div>
        </div>
        <div class="filter-group">
          <label for="f-preis">{t.shop.priceUpTo}</label>
          <input id="f-preis" type="range" min="0" max="110" value="110" />
          <span class="small" id="f-preis-value">{t.shop.priceUpToValue(110)}</span>
        </div>
        <div class="filter-group">
          <label for="f-verfuegbar">{t.shop.onlyAvailable}</label>
          <input id="f-verfuegbar" type="checkbox" />
        </div>
        <div class="filter-group">
          <span id="f-bewertung-label">{t.shop.minRatingLabel}</span>
          <div class="cat-filter" id="rating-filter" data-dropdown>
            <input type="hidden" id="f-bewertung" value="0" />
            <button type="button" class="cat-filter-btn" data-dropdown-btn aria-haspopup="listbox" aria-expanded="false" aria-labelledby="f-bewertung-label">
              <span data-dropdown-current>{t.shop.minRatingAny}</span>
              <span class="chevron" aria-hidden="true">▼</span>
            </button>
            <div class="cat-filter-menu" role="listbox" aria-labelledby="f-bewertung-label">
              <button type="button" class="cat-filter-option" data-value="0" data-label={t.shop.minRatingAny} role="option" aria-selected="true">{t.shop.minRatingAny}</button>
              {[4, 3, 2, 1].map((n) => (
                <button type="button" class="cat-filter-option rating-option" data-value={String(n)} role="option" aria-selected="false">
                  <HeartRating bewertung={n} size={15} />
                  <span class="rating-plus">+</span>
                </button>
              ))}
            </div>
          </div>
        </div>
        <p class="small">{t.shop.filterNote}</p>
      </aside>

      <div>
        <div class="shop-toolbar">
          <span class="small" id="result-count">{t.shop.resultCount(products.length)}</span>
          <select id="sort" aria-label={t.shop.sortLabel}>
            <option value="neu">{t.shop.sortNew}</option>
            <option value="bestseller">{t.shop.sortBestseller}</option>
            <option value="bewertung">{t.shop.sortRating}</option>
            <option value="preis-auf">{t.shop.sortPriceAsc}</option>
            <option value="preis-ab">{t.shop.sortPriceDesc}</option>
          </select>
        </div>
        <div class="grid grid-3" id="product-grid">
          {products.map((p) => (
            <div
              class="product-slot"
              data-slug={p.slug}
              data-kategorie={p.kategorie}
              data-unterkategorie={p.unterkategorie ?? ""}
              data-preis={p.preis}
              data-bestand={p.bestand}
              data-neu={p.badges.includes("neu") ? 1 : 0}
              data-bestseller={p.badges.includes("bestseller") ? 1 : 0}
              data-bewertung={durchschnittsbewertung(p) ?? 0}
              data-basis-anzahl={anzahlBewertungen(p)}
            >
              <ProductCard product={p} lang={lang} />
            </div>
          ))}
        </div>
        <p class="small" id="empty-msg" style="display:none;">{t.shop.noResults}</p>
        <p class="legal-hint small">{t.common.vatNote} {t.common.allPricesPlusShipping}</p>
      </div>
    </div>
  </section>
</Layout>

<script define:vars={{ productSingular: t.shop.productSingular, productPlural: t.shop.productPlural, unitFirst: lang === "en" }}>
  const grid = document.getElementById("product-grid");
  const slots = Array.from(grid.querySelectorAll(".product-slot"));
  const kategorieSel = document.getElementById("f-kategorie");
  const preisRange = document.getElementById("f-preis");
  const preisValue = document.getElementById("f-preis-value");
  const verfuegbarChk = document.getElementById("f-verfuegbar");
  const bewertungSel = document.getElementById("f-bewertung");
  const sortSel = document.getElementById("sort");
  const resultCount = document.getElementById("result-count");
  const emptyMsg = document.getElementById("empty-msg");
  const currencySymbol = "€";

  function formatPrice(v) {
    return unitFirst ? `${currencySymbol}${v}` : `${v} ${currencySymbol}`;
  }

  function apply() {
    const kat = kategorieSel.value;
    const maxPreis = Number(preisRange.value);
    const nurVerfuegbar = verfuegbarChk.checked;
    const minBewertung = Number(bewertungSel.value);
    preisValue.textContent = formatPrice(maxPreis);

    let visible = 0;
    slots.forEach((slot) => {
      const matchKat = !kat
        ? true
        : kat.startsWith("sub:")
          ? slot.dataset.unterkategorie === kat.slice(4)
          : slot.dataset.kategorie === kat;
      const matchPreis = Number(slot.dataset.preis) <= maxPreis;
      const matchVerfuegbar = !nurVerfuegbar || Number(slot.dataset.bestand) > 0;
      const matchBewertung = Number(slot.dataset.bewertung) >= minBewertung;
      const show = matchKat && matchPreis && matchVerfuegbar && matchBewertung;
      slot.style.display = show ? "" : "none";
      if (show) visible++;
    });

    resultCount.textContent = `${visible} ${visible === 1 ? productSingular : productPlural}`;
    emptyMsg.style.display = visible === 0 ? "block" : "none";

    const sorted = [...slots].sort((a, b) => {
      switch (sortSel.value) {
        case "preis-auf": return Number(a.dataset.preis) - Number(b.dataset.preis);
        case "preis-ab": return Number(b.dataset.preis) - Number(a.dataset.preis);
        case "bestseller": return Number(b.dataset.bestseller) - Number(a.dataset.bestseller);
        case "bewertung": return Number(b.dataset.bewertung) - Number(a.dataset.bewertung);
        default: return Number(b.dataset.neu) - Number(a.dataset.neu);
      }
    });
    sorted.forEach((el) => grid.appendChild(el));
  }

  [preisRange, verfuegbarChk, sortSel].forEach((el) => el.addEventListener("input", apply));

  // Eigene Dropdowns (statt nativer <select>-Felder): Der Browser kann in seiner eigenen
  // Auswahlliste weder unsere Kategorie-Struktur noch Verlaufs-Farben darstellen — deshalb hier
  // eine eigene, gestaltbare Liste. Ein gemeinsamer Code für BEIDE Dropdowns (Kategorie und
  // Mindestbewertung), damit sich beide identisch verhalten und es nur eine Stelle zum Pflegen
  // gibt. Verhalten wie beim Sprach-Umschalter im Header.
  const dropdowns = Array.from(document.querySelectorAll("[data-dropdown]")).map((root) => {
    const btn = root.querySelector("[data-dropdown-btn]");
    const current = root.querySelector("[data-dropdown-current]");
    const hidden = root.querySelector("input[type=hidden]");
    const options = Array.from(root.querySelectorAll(".cat-filter-option"));

    function select(value) {
      const opt = options.find((o) => o.dataset.value === value);
      if (!opt) return;
      hidden.value = value;
      // Optionen ohne eigenes data-label (z.B. die Herzen-Zeilen) übernehmen ihren kompletten
      // Inhalt in den Knopf — so stehen dort dieselben Verlaufs-Herzen wie in der Liste.
      if (opt.dataset.label !== undefined) current.textContent = opt.dataset.label;
      else current.innerHTML = opt.innerHTML;
      options.forEach((o) => o.setAttribute("aria-selected", String(o === opt)));
      apply();
    }

    function close() {
      root.classList.remove("open");
      btn.setAttribute("aria-expanded", "false");
    }

    btn.addEventListener("click", (e) => {
      e.stopPropagation();
      const willOpen = !root.classList.contains("open");
      // Immer erst alle anderen schließen, damit nie zwei Listen gleichzeitig offen sind.
      document.querySelectorAll("[data-dropdown].open").forEach((other) => {
        other.classList.remove("open");
        other.querySelector("[data-dropdown-btn]").setAttribute("aria-expanded", "false");
      });
      if (willOpen) {
        root.classList.add("open");
        btn.setAttribute("aria-expanded", "true");
      }
    });

    options.forEach((opt) => {
      opt.addEventListener("click", () => {
        select(opt.dataset.value);
        close();
      });
    });

    return { root, close, select, options };
  });

  document.addEventListener("click", () => dropdowns.forEach((d) => d.close()));
  document.addEventListener("keydown", (e) => {
    if (e.key === "Escape") dropdowns.forEach((d) => d.close());
  });

  // Voreinstellung über die Adresszeile (z.B. /shop/?kategorie=diy-plushies), damit Links aus
  // der Navigation weiterhin direkt mit gesetztem Filter landen.
  const params = new URLSearchParams(location.search);
  const preset = params.get("kategorie");
  if (preset) dropdowns.forEach((d) => d.select(preset));

  // Rezensionen, die auf DIESEM Gerät lokal gespeichert wurden (siehe scripts/reviews.ts),
  // werden in einem eigenen (Modul-)Skript direkt im Anschluss eingerechnet — dieses Skript
  // hier nutzt define:vars und darf deshalb selbst kein "import" enthalten (siehe unten).
  window.__shopApply = apply;
  apply();
</script>

<script>
  import { lokaleBewertungenFuer } from "../../../scripts/reviews";

  // Lokal auf diesem Gerät gespeicherte Kundenrezensionen (siehe scripts/reviews.ts) in
  // data-bewertung einrechnen und danach neu filtern/sortieren — sonst würden der
  // Mindestbewertung-Filter und die Sortierung "Beste Bewertung" neue Rezensionen ignorieren.
  const slots = Array.from(document.querySelectorAll(".product-slot"));
  slots.forEach((slot) => {
    const slug = slot.dataset.slug;
    if (!slug) return;
    const lokale = lokaleBewertungenFuer(slug);
    if (lokale.length === 0) return;
    const basisSchnitt = Number(slot.dataset.bewertung || 0);
    const basisAnzahl = Number(slot.dataset.basisAnzahl || 0);
    const summe = basisSchnitt * basisAnzahl + lokale.reduce((s, r) => s + r.bewertung, 0);
    slot.dataset.bewertung = String(summe / (basisAnzahl + lokale.length));
  });
  (window as any).__shopApply?.();
</script>
