/* ── Stien — main app ──────────────────────────────────────────────────── */

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/ {
  "cardStyle": "fijn",
  "previewStijl": "banner",
  "kalenderStijl": "maand",
  "wordmark": ["#DD7A45", "#D4B23C", "#BE6CAE", "#DD7A45", "#BE6CAE"],
  "showBlobs": true
} /*EDITMODE-END*/;

const BANK = window.STIEN_BANK;
const META = window.STIEN_META;
const GIFTS = window.STIEN_GIFTS;

const BLOB_PALETTE = { purple: "#C26FB3", orange: "#E8743B", yellow: "#D7CE3F" };

const euro = (n) =>
  "€ " + Number(n).toLocaleString("nl-BE", { minimumFractionDigits: 0 });

/* ── reserved (al gekozen) state, persisted locally ── */
function useReserved() {
  const KEY = "stien_reserved_v1";
  const [set, setSet] = useState(() => {
    try { return new Set(JSON.parse(localStorage.getItem(KEY) || "[]")); }
    catch { return new Set(); }
  });
  const toggle = (id) =>
    setSet((prev) => {
      const next = new Set(prev);
      next.has(id) ? next.delete(id) : next.add(id);
      localStorage.setItem(KEY, JSON.stringify([...next]));
      return next;
    });
  return [set, toggle];
}

/* ── gift cards — several minimal styles, switchable via Tweaks ──
   variants: zacht · icoon · helder · minimaal · fijn                  */
const STAMP_COLORS = ["#C26FB3", "#E8743B", "#D7CE3F"];

function priceLabel(gift) {
  if (gift.type === "kraam") return "kies een dag";
  return gift.open ? "vrij bedrag" : euro(gift.prijs);
}

function GiftCard({ gift, reserved, onOpen, variant, index, color }) {
  const isAction = gift.open || gift.type === "kraam";
  const cls =
    "gift gv-" + variant +
    (reserved ? " is-reserved" : "") +
    (isAction ? " is-open" : "");
  const cta = gift.type === "kraam" ? "kies een dag"
            : gift.open ? "geef een bedrag" : "dit cadeau geven";
  const ctaShort = "geven";
  const open = () => onOpen(gift);
  const tag = reserved && <span className="gift-tag">al gekozen ✓</span>;

  /* ── minimaal: borderless, hairline, text-link ── */
  if (variant === "minimaal") {
    return (
      <article className={cls} onClick={open}>
        <div className="m-top">
          <h3 className="gift-title">{gift.titel}</h3>
          <span className="gift-price">{priceLabel(gift)}</span>
        </div>
        <p className="gift-desc">{gift.omschrijving}</p>
        <span className="m-link">{tag || <>{ctaShort} <span className="btn-arrow">→</span></>}</span>
      </article>
    );
  }

  /* ── fijn: indexed editorial, whole card is the button ── */
  if (variant === "fijn") {
    return (
      <button className={cls} onClick={open}>
        <h3 className="gift-title">{gift.titel}</h3>
        <p className="gift-desc">{gift.omschrijving}</p>
        <div className="f-foot">
          {gift.icon
            ? <GiftMark name={gift.icon} />
            : <span className="f-index">{String(index + 1).padStart(2, "0")}</span>}
          {reserved
            ? <span className="gift-tag">al gekozen ✓</span>
            : <span className="f-price">{priceLabel(gift)}</span>}
        </div>
      </button>
    );
  }

  /* ── helder: clear / readable, badge price, full button ── */
  if (variant === "helder") {
    return (
      <article className={cls}>
        <span className="h-badge">{priceLabel(gift)}</span>
        <h3 className="gift-title">{gift.titel}</h3>
        <p className="gift-desc">{gift.omschrijving}</p>
        <button className="h-btn" onClick={open} disabled={reserved}>
          {reserved ? "al gekozen ✓" : cta}
        </button>
      </article>
    );
  }

  /* ── icoon: small riso-stamp mark ── */
  if (variant === "icoon") {
    return (
      <article className={cls}>
        <span className="gift-icon" style={{ background: color, filter: "url(#riso-b)" }} aria-hidden="true" />
        <div className="gift-top">
          <h3 className="gift-title">{gift.titel}</h3>
          <span className="gift-price">{priceLabel(gift)}</span>
        </div>
        <p className="gift-desc">{gift.omschrijving}</p>
        <div className="gift-foot">
          {tag || <span className="gift-dot" style={{ background: gift.open ? BLOB_PALETTE.yellow : "transparent" }} />}
          <button className="btn" onClick={open}>{cta}<span className="btn-arrow">→</span></button>
        </div>
      </article>
    );
  }

  /* ── zacht (default): soft tile ── */
  return (
    <article className={cls}>
      <div className="gift-top">
        <h3 className="gift-title">{gift.titel}</h3>
        <span className="gift-price">{priceLabel(gift)}</span>
      </div>
      <p className="gift-desc">{gift.omschrijving}</p>
      <div className="gift-foot">
        {tag || <span className="gift-dot" style={{ background: gift.open ? BLOB_PALETTE.yellow : "transparent" }} />}
        <button className="btn" onClick={open}>{cta}<span className="btn-arrow">→</span></button>
      </div>
    </article>
  );
}

/* ── payment modal (spaarpot / open amounts) ── */
function PayModal({ gift, onClose, preview }) {
  const [tab, setTab] = useState("qr");
  const [amount, setAmount] = useState(gift.open ? 25 : gift.prijs);
  const [mededeling, setMededeling] = useState(`${BANK.mededeling} - ${gift.titel}`);
  const [memoOpen, setMemoOpen] = useState(false);
  const memoInputRef = useRef(null);
  const valid = Number(amount) > 0;

  const payload = window.buildEpcPayload({
    begunstigde: BANK.begunstigde,
    iban: BANK.iban,
    bic: BANK.bic,
    bedrag: valid ? amount : 0,
    mededeling,
  });
  const svg = valid ? window.epcQrSvg(payload, { cell: 7, margin: 4 }) : "";

  useEffect(() => {
    const onKey = (e) => e.key === "Escape" && onClose();
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);

  useEffect(() => {
    if (memoOpen) memoInputRef.current && memoInputRef.current.focus();
  }, [memoOpen]);

  return (
    <div className="modal-scrim" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()}>
        <button className="modal-close" onClick={onClose} aria-label="Sluiten">×</button>

        <div className="modal-head">
          <p className="eyebrow">cadeau voor Stien</p>
          <h2 className="modal-title">{gift.titel}</h2>
        </div>

        <GiftPreview gift={gift} variant={preview} />

        {gift.open && (
          <div className="amount-pick">
            <span className="amount-label">ik geef</span>
            <div className="amount-field">
              <span>€</span>
              <input
                type="number" min="1" step="1" value={amount}
                onChange={(e) => setAmount(e.target.value)}
              />
            </div>
            <p className="amount-help">Pas het bedrag gerust aan.</p>
          </div>
        )}

        {gift.open && (
          memoOpen ? (
            <div className="memo-pick">
              <label className="memo-label" htmlFor="payment-memo">mededeling</label>
              <input
                id="payment-memo"
                ref={memoInputRef}
                className="memo-input"
                type="text"
                maxLength="140"
                value={mededeling}
                aria-describedby="payment-memo-help payment-memo-count"
                onChange={(e) => setMededeling(e.target.value)}
              />
              <div className="memo-meta">
                <span id="payment-memo-help">Laat gerust staan, of zet er je naam bij.</span>
                <span id="payment-memo-count" className="memo-count">{mededeling.length}/140</span>
              </div>
            </div>
          ) : (
            <button className="memo-summary" type="button" onClick={() => setMemoOpen(true)}>
              <span className="memo-summary-label">mededeling</span>
              <span className="memo-summary-value">{mededeling}</span>
              <span className="memo-summary-action">wijzig</span>
            </button>
          )
        )}

        <div className="tabs">
          <button className={"tab" + (tab === "qr" ? " on" : "")} onClick={() => setTab("qr")}>
            Scan en betaal
          </button>
          <button className={"tab" + (tab === "ovs" ? " on" : "")} onClick={() => setTab("ovs")}>
            Overschrijving
          </button>
        </div>

        {tab === "qr" ? (
          <div className="qr-pane">
            <div className="qr-card">
              {valid ? (
                <div className="qr-img" dangerouslySetInnerHTML={{ __html: svg }} />
              ) : (
                <div className="qr-empty">kies eerst een bedrag</div>
              )}
            </div>
            <div className="qr-side">
              <p className="qr-note">
                Scan met je bankapp: KBC, Belfius, ING, Argenta, BNP Paribas Fortis.
                Bedrag en mededeling staan al ingevuld.
              </p>
            </div>
          </div>
        ) : (
          <div className="ovs-pane">
            <CopyRow label="begunstigde" value={BANK.begunstigde} mono={false} />
            <CopyRow label="IBAN" value={BANK.iban} />
            <CopyRow label="bedrag" value={valid ? euro(amount) : "—"} />
            <CopyRow label="mededeling" value={mededeling} mono={false} />
            <p className="ovs-note">Tik op een regel om te kopiëren.</p>
          </div>
        )}

        <div className="modal-foot">
          <p className="open-note">Dankjewel om mee te sparen voor later.</p>
        </div>
      </div>
    </div>
  );
}

/* ── kraamkost modal (meal-train calendar) ── */
function KraamModal({ gift, onClose, preview, calStyle }) {
  const kk = useBookings(gift.bezet);
  const slots = kkGiftSlots(gift);
  const locked = gift.locked || {};

  useEffect(() => {
    const onKey = (e) => e.key === "Escape" && onClose();
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);

  return (
    <div className="modal-scrim" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()}>
        <button className="modal-close" onClick={onClose} aria-label="Sluiten">×</button>
        <div className="modal-head">
          <p className="eyebrow">cadeau voor Stien</p>
          <h2 className="modal-title">{gift.titel}</h2>
        </div>
        <GiftPreview gift={gift} variant={preview} />
        <KraamCalendar slots={slots} bookings={{ booked: kk.map, locked }} mine={kk.mine}
          onBook={kk.book} onRename={kk.rename} onRelease={kk.release} variant={calStyle} />
        <div className="modal-foot">
          <p className="open-note">Dankjewel om mee te zorgen voor eten.</p>
        </div>
      </div>
    </div>
  );
}

/* ── page ── */
function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [active, setActive] = useState(null);

  const blobs = t.showBlobs;

  return (
    <div className="page">
      {/* paper grain overlay */}
      <div className="grain" aria-hidden="true" />

      <header className="hero">
        {blobs && (
          <Blob color={BLOB_PALETTE.purple} w={304} h={248} rot={-5} filter="riso-a"
            radius="46% 54% 52% 48% / 60% 58% 42% 40%" className="stamp-hero" />
        )}
        <div className="hero-inner">
          <img className="hero-logo" src="assets/stien.svg" alt="Stien" />
          <p className="born">{META.geboren}</p>
          <p className="lede">
            Twee manieren om mee te vieren: kom eens langs met een maaltijd,
            of leg iets opzij voor later. Alles is welkom, niets is verplicht.
          </p>
        </div>
      </header>

      <main className="gifts-wrap">
        {blobs && (
          <Blob color={BLOB_PALETTE.yellow} w={352} h={212} rot={4} filter="riso-b"
            radius="50% 50% 48% 52% / 54% 50% 50% 46%" className="stamp-gifts" />
        )}
        <div className="section-head">
          <span className="rule" />
          <h2>zo kan je helpen</h2>
          <span className="rule" />
        </div>

        <div className={"gifts kaart-" + t.cardStyle}>
          {GIFTS.map((g, i) => (
            <GiftCard
              key={g.id}
              gift={g}
              index={i}
              color={STAMP_COLORS[i % STAMP_COLORS.length]}
              variant={t.cardStyle}
              reserved={false}
              onOpen={setActive}
            />
          ))}
        </div>
      </main>

      <footer className="foot">
        {blobs && (
          <Blob color={BLOB_PALETTE.orange} w={262} h={244} rot={6} filter="riso-c"
            radius="52% 48% 46% 54% / 50% 56% 44% 50%" className="stamp-foot" />
        )}
        <p>liefs, Lori, Bram &amp; Tuur</p>
      </footer>

      {active && (active.type === "kraam" ? (
        <KraamModal
          key={active.id}
          gift={active}
          onClose={() => setActive(null)}
          preview={t.previewStijl}
          calStyle={t.kalenderStijl}
        />
      ) : (
        <PayModal
          key={active.id}
          gift={active}
          onClose={() => setActive(null)}
          preview={t.previewStijl}
        />
      ))}

      {/* ── Tweaks ── */}
      <TweaksPanel>
        <TweakSection label="Vlekken" />
        <TweakToggle label="Stempels tonen" value={t.showBlobs}
          onChange={(v) => setTweak("showBlobs", v)} />

        <TweakSection label="Cadeaus" />
        <TweakSelect label="Kaartstijl" value={t.cardStyle}
          options={["zacht", "icoon", "helder", "minimaal", "fijn"]}
          onChange={(v) => setTweak("cardStyle", v)} />

        <TweakSection label="Cadeau-voorbeeld (in venster)" />
        <TweakSelect label="Stijl" value={t.previewStijl}
          options={[
            { value: "geen", label: "geen — meteen openen" },
            { value: "banner", label: "banner — brede foto boven" },
            { value: "compact", label: "compact — kleine thumbnail" },
            { value: "groot", label: "groot — grote foto" },
          ]}
          onChange={(v) => setTweak("previewStijl", v)} />

        <TweakSection label="Kraamkost-kalender" />
        <TweakSelect label="Kalenderstijl" value={t.kalenderStijl}
          options={[
            { value: "maand", label: "maand — kalenderrooster" },
            { value: "lijst", label: "lijst — dagen onder elkaar" },
            { value: "week", label: "week — dagen als chips" },
          ]}
          onChange={(v) => setTweak("kalenderStijl", v)} />

        <TweakSection label="STIEN — kleuren" />
        <TweakColor label="Letterkleuren" value={t.wordmark}
          options={[
            ["#DD7A45", "#D4B23C", "#BE6CAE", "#DD7A45", "#BE6CAE"],
            ["#DD7A45", "#D4B23C", "#D8662F", "#DD7A45", "#D8662F"],
            ["#BE6CAE", "#C77FB8", "#A85C9C", "#BE6CAE", "#A85C9C"],
            ["#36424E", "#36424E", "#36424E", "#36424E", "#36424E"],
          ]}
          onChange={(v) => setTweak("wordmark", v)} />
      </TweaksPanel>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
