// Views: Landing, Picker, Form, Confirm, Admin

const { useState, useEffect, useMemo, useRef } = React;

// ---------- LANDING (BOLD / EDITORIAL MAGAZINE) ----------
function LandingBold({ onStart }) {
  return (
    <div className="view landing-bold" data-screen-label="01 Landing · Bold">

      {/* MASTHEAD */}
      <div className="lb-masthead">
        <div className="lb-mast-left">
          <span className="lb-mast-issue">Vol. 01 · Ausgabe Mai 2026</span>
        </div>
        <div className="lb-mast-center">CBES · Blutspende</div>
        <div className="lb-mast-right">
          <span className="lb-mast-date">{ACTION_INFO.dateLabel}</span>
        </div>
      </div>

      {/* HERO POSTER */}
      <section className="lb-poster">
        <div className="lb-poster-grid">

          {/* Big numeral */}
          <div className="lb-cell lb-cell-numeral">
            <div className="lb-numeral">03</div>
            <div className="lb-numeral-label">
              <div className="lb-tick"></div>
              <div>
                <b>Leben gerettet</b><br/>
                <span>pro Spende</span>
              </div>
            </div>
          </div>

          {/* Headline */}
          <div className="lb-cell lb-cell-headline">
            <div className="lb-kicker">
              <span className="lb-kicker-bar"></span>
              Aktion am 12. Mai
            </div>
            <h1 className="lb-h1">
              Roll up<br/>
              your <em>sleeve</em>.<br/>
              <span className="lb-h1-mute">Save a life.</span>
            </h1>
            <p className="lb-lede">
              15 Minuten in der großen Pause.<br/>
              Vier Plätze parallel. Über hundert offene Slots.
            </p>
            <button className="btn btn-cta lb-cta" onClick={onStart}>
              <span className="cta-pulse" aria-hidden="true"></span>
              Slot reservieren <span className="arrow">→</span>
            </button>
          </div>

          {/* Time stamp tile */}
          <div className="lb-cell lb-cell-time">
            <div className="lb-time-label">When</div>
            <div className="lb-time-day">DI</div>
            <div className="lb-time-num">12</div>
            <div className="lb-time-month">MAI 2026</div>
            <div className="lb-time-window">09:00 — 16:00</div>
          </div>

          {/* Place tile */}
          <div className="lb-cell lb-cell-place">
            <div className="lb-place-label">Where</div>
            <div className="lb-place-name">Haus D</div>
            <div className="lb-place-school">{ACTION_INFO.location}</div>
            <a className="lb-place-addr" href={ACTION_INFO.mapsUrl} target="_blank" rel="noopener noreferrer">
              {ACTION_INFO.address}
              <span className="lb-arrow-out">↗</span>
            </a>
          </div>

          {/* Stat band */}
          <div className="lb-cell lb-cell-stats">
            <div className="lb-stat-item">
              <div className="lb-stat-num">15<sup>min</sup></div>
              <div className="lb-stat-lbl">pro Termin</div>
            </div>
            <div className="lb-stat-item">
              <div className="lb-stat-num">112</div>
              <div className="lb-stat-lbl">freie Slots</div>
            </div>
            <div className="lb-stat-item">
              <div className="lb-stat-num">×4</div>
              <div className="lb-stat-lbl">parallel spenden</div>
            </div>
            <div className="lb-stat-item">
              <div className="lb-stat-num">500<sup>ml</sup></div>
              <div className="lb-stat-lbl">eine Spende</div>
            </div>
          </div>

        </div>
      </section>

      {/* TICKER */}
      <div className="lb-ticker" aria-hidden="true">
        <div className="lb-ticker-inner">
          {Array.from({length: 6}).map((_, i) => (
            <span key={i} className="lb-ticker-piece">
              <span>Termin buchen</span>
              <span className="lb-ticker-bullet">●</span>
              <span>15 Minuten</span>
              <span className="lb-ticker-bullet">●</span>
              <span>3 Leben gerettet</span>
              <span className="lb-ticker-bullet">●</span>
              <span>CBES Lollar</span>
              <span className="lb-ticker-bullet">●</span>
            </span>
          ))}
        </div>
      </div>

      {/* MANIFESTO / WHY */}
      <section className="lb-manifesto">
        <div className="lb-manifesto-grid">
          <div className="lb-manifesto-meta">
            <div className="lb-tag-row">
              <span className="lb-tag">№ 01</span>
              <span className="lb-tag-line">Warum mitmachen</span>
            </div>
            <h2 className="lb-h2">
              Eine halbe Stunde deiner Zeit ist <em>genug</em>, um in einer Klinik einen Tag zu retten.
            </h2>
          </div>
          <div className="lb-manifesto-body">
            <p className="lb-drop">
              <span className="lb-drop-cap">B</span>lutkonserven sind dauerhaft knapp – besonders im Frühjahr und um Ferienzeiten herum. Eine einzige Spende kann bis zu drei Patient:innen helfen: bei Operationen, nach Unfällen, in der Krebstherapie.
            </p>
            <p>
              Du musst kein Held:in sein, um zu spenden. Es reicht, gesund zu sein, gefrühstückt zu haben – und dir eine kurze Pause vom Schultag zu nehmen.
            </p>
            <ul className="lb-bullets">
              <li><span className="lb-bullet-num">01</span><span>Spende dauert ca. <b>10 Minuten</b>, gesamter Termin etwa <b>30 Minuten</b> inkl. Vorgespräch.</span></li>
              <li><span className="lb-bullet-num">02</span><span>Du wirst <b>kostenlos auf wichtige Werte untersucht</b> – ein kleiner Gesundheitscheck nebenbei.</span></li>
              <li><span className="lb-bullet-num">03</span><span><b>Bescheinigung für die Schule</b> gibt's am Stand auf Wunsch.</span></li>
            </ul>
          </div>
        </div>
      </section>

      {/* PREP CHECKLIST AS POSTER */}
      <section className="lb-prep">
        <div className="lb-prep-head">
          <div className="lb-tag-row">
            <span className="lb-tag">№ 02</span>
            <span className="lb-tag-line">Vor der Spende</span>
          </div>
          <h2 className="lb-h2">
            Vier Dinge, an die <em>alle</em> denken sollten.
          </h2>
        </div>
        <div className="lb-prep-grid">
          <div className="lb-prep-card">
            <div className="lb-prep-num">01</div>
            <div className="lb-prep-rule"></div>
            <h3>Ausweis</h3>
            <p>Lichtbildausweis nicht vergessen — ohne geht's leider nicht.</p>
          </div>
          <div className="lb-prep-card lb-prep-card-dark">
            <div className="lb-prep-num">02</div>
            <div className="lb-prep-rule"></div>
            <h3>Frühstück</h3>
            <p>Vor dem Termin ordentlich essen — kein Kreislauf, kein Drama.</p>
          </div>
          <div className="lb-prep-card">
            <div className="lb-prep-num">03</div>
            <div className="lb-prep-rule"></div>
            <h3>1,5 L Wasser</h3>
            <p>Vor und nach der Spende reichlich trinken — Tee oder Saftschorle gehen auch.</p>
          </div>
          <div className="lb-prep-card lb-prep-card-accent">
            <div className="lb-prep-num">04</div>
            <div className="lb-prep-rule"></div>
            <h3>Kein Sport</h3>
            <p>12 Stunden vor und nach der Spende kein intensives Training.</p>
          </div>
        </div>
      </section>

      {/* COLOPHON / FINAL CTA */}
      <section className="lb-colophon">
        <div className="lb-colophon-inner">
          <div className="lb-colophon-meta">
            <div className="lb-tag-row">
              <span className="lb-tag lb-tag-light">№ 03</span>
              <span className="lb-tag-line lb-tag-line-light">Jetzt dabei</span>
            </div>
            <h2 className="lb-h2 lb-h2-light">
              Buch dir <em>jetzt</em> deinen 15-Minuten-Slot.
            </h2>
            <p className="lb-colophon-p">
              Du brauchst keine Anmeldung im Vorfeld, kein Konto, keine App. Wähle einen Termin, hinterlasse Name, E-Mail und Telefon – fertig.
            </p>
            <button className="btn btn-cta lb-cta lb-cta-light" onClick={onStart}>
              <span className="cta-pulse" aria-hidden="true"></span>
              Termin buchen <span className="arrow">→</span>
            </button>
          </div>
          <div className="lb-colophon-side">
            <div className="lb-colophon-row"><span>Veranstalter</span><b>{ACTION_INFO.organizer}</b></div>
            <div className="lb-colophon-row"><span>Datum</span><b>{ACTION_INFO.dateLabel}</b></div>
            <div className="lb-colophon-row"><span>Zeit</span><b>{ACTION_INFO.timeLabel}</b></div>
            <div className="lb-colophon-row"><span>Ort</span><b>{ACTION_INFO.location}</b></div>
            <div className="lb-colophon-row"><span>Adresse</span><b>{ACTION_INFO.address}</b></div>
            <div className="lb-colophon-row"><span>Slots</span><b>112 · vier parallel</b></div>
          </div>
        </div>
      </section>

    </div>
  );
}

// ---------- LANDING (MODERN) ----------
function LandingModern({ onStart }) {
  return (
    <div className="view landing-modern" data-screen-label="01 Landing · Modern">
      {/* HERO */}
      <section className="lm-hero">
        <div className="lm-hero-bg" aria-hidden="true">
          <div className="lm-blob lm-blob-1"></div>
          <div className="lm-blob lm-blob-2"></div>
          <svg className="lm-grid-svg" viewBox="0 0 1200 600" preserveAspectRatio="none">
            <defs>
              <pattern id="lm-grid" width="48" height="48" patternUnits="userSpaceOnUse">
                <path d="M 48 0 L 0 0 0 48" fill="none" stroke="currentColor" strokeWidth="0.5" opacity="0.4"/>
              </pattern>
            </defs>
            <rect width="100%" height="100%" fill="url(#lm-grid)"/>
          </svg>
        </div>

        <div className="lm-hero-inner">
          <div className="lm-tag">
            <span className="lm-tag-dot"></span>
            <span>Aktion · {ACTION_INFO.dateLabel}</span>
            <span className="lm-tag-sep"></span>
            <span className="lm-tag-mute">Haus D · CBES Lollar</span>
          </div>

          <h1 className="lm-h1">
            Eine Spende.<br/>
            <span className="lm-h1-accent">Drei Leben.</span>
          </h1>

          <p className="lm-lede">
            Buche in unter einer Minute deinen 15-Minuten-Termin am 12. Mai – die Spende selbst dauert nur etwa zehn Minuten.
          </p>

          <div className="lm-cta-row">
            <button className="btn btn-cta lm-cta" onClick={onStart}>
              <span className="cta-pulse" aria-hidden="true"></span>
              Jetzt Termin buchen
              <span className="arrow">→</span>
            </button>
            <a className="lm-link" href="#lm-info">
              Wie läuft das ab? <span className="lm-link-arrow">↓</span>
            </a>
          </div>

          {/* metric strip */}
          <div className="lm-metrics">
            <div className="lm-metric">
              <div className="lm-metric-num">15<span className="u">min</span></div>
              <div className="lm-metric-lbl">pro Termin</div>
            </div>
            <div className="lm-metric-sep" aria-hidden="true"></div>
            <div className="lm-metric">
              <div className="lm-metric-num">112</div>
              <div className="lm-metric-lbl">freie Slots</div>
            </div>
            <div className="lm-metric-sep" aria-hidden="true"></div>
            <div className="lm-metric">
              <div className="lm-metric-num">≈3</div>
              <div className="lm-metric-lbl">gerettete Leben</div>
            </div>
            <div className="lm-metric-sep" aria-hidden="true"></div>
            <div className="lm-metric">
              <div className="lm-metric-num">500<span className="u">ml</span></div>
              <div className="lm-metric-lbl">eine Spende</div>
            </div>
          </div>
        </div>
      </section>

      {/* INFO CARDS */}
      <section className="lm-info" id="lm-info">
        <div className="lm-section-head">
          <span className="lm-eyebrow">Vorbereitung</span>
          <h2 className="lm-h2">In drei Schritten zur Spende.</h2>
        </div>

        <div className="lm-steps">
          <article className="lm-step">
            <div className="lm-step-num">01</div>
            <h3 className="lm-step-title">Termin wählen</h3>
            <p className="lm-step-text">
              Such dir einen 15-Minuten-Slot zwischen 09:00 und 16:00, der zu deinem Stundenplan passt. Vier Personen können parallel spenden.
            </p>
          </article>

          <article className="lm-step lm-step-accent">
            <div className="lm-step-num">02</div>
            <h3 className="lm-step-title">Gut vorbereiten</h3>
            <p className="lm-step-text">
              Frühstück nicht vergessen, mindestens 1,5&nbsp;Liter trinken, und keinen intensiven Sport in den 12 Stunden davor.
            </p>
          </article>

          <article className="lm-step">
            <div className="lm-step-num">03</div>
            <h3 className="lm-step-title">Spenden & stärken</h3>
            <p className="lm-step-text">
              Lichtbildausweis mitbringen, am Stand anmelden – danach warten Snacks, Kaffee und ein gutes Gefühl.
            </p>
          </article>
        </div>
      </section>

      {/* BIG INFO STRIP */}
      <section className="lm-strip">
        <div className="lm-strip-inner">
          <div className="lm-strip-cell">
            <div className="lm-strip-key">Datum</div>
            <div className="lm-strip-val">{ACTION_INFO.dateLabel}</div>
          </div>
          <div className="lm-strip-cell">
            <div className="lm-strip-key">Zeitfenster</div>
            <div className="lm-strip-val">{ACTION_INFO.timeLabel}</div>
          </div>
          <div className="lm-strip-cell">
            <div className="lm-strip-key">Ort</div>
            <div className="lm-strip-val">
              {ACTION_INFO.location}
              <a href={ACTION_INFO.mapsUrl} target="_blank" rel="noopener noreferrer" className="lm-strip-link" title="In Google Maps öffnen">
                {ACTION_INFO.address} <span aria-hidden="true">↗</span>
              </a>
            </div>
          </div>
          <div className="lm-strip-cell">
            <div className="lm-strip-key">Veranstalter</div>
            <div className="lm-strip-val lm-strip-val-sm">{ACTION_INFO.organizer}</div>
          </div>
        </div>
      </section>

      {/* QUICK FACTS / CHECKLIST */}
      <section className="lm-facts">
        <div className="lm-facts-grid">
          <div className="lm-facts-head">
            <span className="lm-eyebrow">Gut zu wissen</span>
            <h2 className="lm-h2">Wer darf spenden?</h2>
            <p className="lm-h2-sub">
              Wenn du gesund bist und dich wohlfühlst, bist du wahrscheinlich startklar. Die wichtigsten Punkte im Überblick:
            </p>
          </div>
          <ul className="lm-facts-list">
            <li><span className="lm-check">✓</span><span><b>Mindestalter 18</b>, gültiger Lichtbildausweis am Stand.</span></li>
            <li><span className="lm-check">✓</span><span><b>Gewicht ≥ 50&nbsp;kg</b> und körperlich fit.</span></li>
            <li><span className="lm-check">✓</span><span>Erstspender:innen <b>bis 64 Jahre</b>, danach nach Rücksprache.</span></li>
            <li><span className="lm-check">✓</span><span>Kein Fieber, kein Infekt in den letzten <b>4 Wochen</b>.</span></li>
            <li><span className="lm-check">✓</span><span>Eine <b>Bescheinigung</b> für die Schule gibt's auf Wunsch direkt am Stand.</span></li>
          </ul>
        </div>
      </section>

      {/* FINAL CTA */}
      <section className="lm-final">
        <div className="lm-final-inner">
          <h2 className="lm-final-h2">Bereit, jemandem das Leben zu retten?</h2>
          <p className="lm-final-p">15 Minuten deiner Zeit. Bis zu drei gerettete Leben.</p>
          <button className="btn btn-cta lm-cta lm-cta-final" onClick={onStart}>
            <span className="cta-pulse" aria-hidden="true"></span>
            Termin buchen <span className="arrow">→</span>
          </button>
        </div>
      </section>
    </div>
  );
}

// ---------- LANDING (EDITORIAL — original) ----------
function Landing({ onStart }) {
  return (
    <div className="view" data-screen-label="01 Landing">
      <div className="landing-grid">
        <div>
          <span className="eyebrow"><span className="dot"></span>Termin buchen · 12. Mai 2026</span>
          <h1 className="display">Drei Leben retten in <em>einer Stunde</em>.</h1>
          <p className="lede">
            Die Clemens-Brentano-Europaschule Lollar lädt zur Blutspende-Aktion in Haus D ein. Wähle einen 15-Minuten-Slot, der zu deinem Stundenplan passt – die Spende selbst dauert nur etwa zehn Minuten.
          </p>

          <div className="facts">
            <dl><dt>Datum</dt><dd>{ACTION_INFO.dateLabel}</dd></dl>
            <dl><dt>Zeitfenster</dt><dd>{ACTION_INFO.timeLabel}</dd></dl>
            <dl><dt>Ort</dt><dd>
              {ACTION_INFO.location}, {ACTION_INFO.address}
              {" "}
              <a href={ACTION_INFO.mapsUrl} target="_blank" rel="noopener noreferrer" className="map-pin" title="In Google Maps öffnen" aria-label="In Google Maps öffnen">📍</a>
            </dd></dl>
            <dl><dt>Veranstalter</dt><dd>{ACTION_INFO.organizer}</dd></dl>
            <dl><dt>Dauer pro Slot</dt><dd>15 Minuten · 4 Plätze parallel</dd></dl>
          </div>

          <div className="cta-row">
            <button className="btn btn-cta" onClick={onStart}>
              <span className="cta-pulse" aria-hidden="true"></span>
              Jetzt Slot buchen <span className="arrow">→</span>
            </button>
            <a className="btn btn-ghost" href="#info">Infos zur Spende</a>
          </div>

          <div className="stats">
            <div><span className="num">112</span><span className="lbl">Slots verfügbar</span></div>
            <div><span className="num">15&nbsp;min</span><span className="lbl">pro Termin</span></div>
            <div><span className="num">≈ 3</span><span className="lbl">Leben pro Spende</span></div>
          </div>
        </div>

        <aside className="side-card" id="info">
          <h3>Was du vorher wissen solltest</h3>
          <ul className="checklist">
            <li><span className="num">01</span><span><b>Mindestalter 18</b>, gültiger Lichtbildausweis bei Anmeldung am Stand.</span></li>
            <li><span className="num">02</span><span><b>Gut frühstücken</b> und mindestens 1,5 Liter Wasser oder Tee am Spendentag.</span></li>
            <li><span className="num">03</span><span><b>Kein intensiver Sport</b> 12 Stunden vor und nach der Spende.</span></li>
            <li><span className="num">04</span><span>Nach der Spende warten <b>Snacks, Kaffee und Verpflegung</b> im Aufenthaltsbereich.</span></li>
            <li><span className="num">05</span><span>Volljährige Schüler:innen erhalten auf Wunsch eine <b>Bescheinigung</b> – einfach am Stand fragen.</span></li>
          </ul>
        </aside>
      </div>
    </div>
  );
}

// ---------- SLOT PICKER ----------
function SlotPicker({ bookings, onPick, onBack, layout }) {
  const slotData = ALL_SLOTS.map(s => {
    const taken = bookings.filter(b => b.slotId === s.id).length;
    return { ...s, taken, free: SLOT_CAPACITY - taken, full: taken >= SLOT_CAPACITY };
  });
  const totalFree = slotData.reduce((a,s)=>a+s.free, 0);
  const totalSlots = slotData.length * SLOT_CAPACITY;

  return (
    <div className="view" data-screen-label="02 Slot-Auswahl">
      <button className="btn btn-ghost" onClick={onBack} style={{marginBottom: 28, padding: "8px 16px", fontSize: 13}}>
        ← Zurück
      </button>
      <div className="section-head">
        <div>
          <span className="eyebrow"><span className="dot"></span>Schritt 1 von 3</span>
          <h2>Wähle deinen Termin</h2>
        </div>
        <div className="meta">
          {ACTION_INFO.dateLabel.toUpperCase()}<br/>
          <b>{totalFree}</b> von {totalSlots} Plätzen frei
        </div>
      </div>

      {layout === "linear" && <SlotsLinear slots={slotData} onPick={onPick}/>}
      {layout === "grid" && <SlotsGrid slots={slotData} onPick={onPick}/>}
      {layout === "schedule" && <SlotsSchedule slots={slotData} onPick={onPick}/>}
    </div>
  );
}

function SlotsLinear({ slots, onPick }) {
  return (
    <div className="slots-linear">
      {slots.map(s => (
        <div key={s.id} className={"slot-row" + (s.full ? " is-full" : "")}
             onClick={() => !s.full && onPick(s)}>
          <div className="time">{s.start}<span className="end"> – {s.end}</span></div>
          <div className="bar"><i style={{width: `${(s.taken/SLOT_CAPACITY)*100}%`}}/></div>
          <div className="availability">
            <b>{s.free}</b> {s.free === 1 ? "Platz" : "Plätze"} frei <span style={{color:"var(--ink-faint)"}}>· {s.taken}/{SLOT_CAPACITY}</span>
          </div>
          <div className="pick">{s.full ? "Ausgebucht" : "Wählen →"}</div>
        </div>
      ))}
    </div>
  );
}

function SlotsGrid({ slots, onPick }) {
  return (
    <div className="slots-grid">
      {slots.map(s => (
        <button key={s.id} className={"slot-card" + (s.full ? " is-full" : "")}
                onClick={() => !s.full && onPick(s)} disabled={s.full}>
          <div className="time">{s.start}</div>
          <div className="label">{s.full ? "Ausgebucht" : `${s.free} von ${SLOT_CAPACITY} Plätzen frei`}</div>
          <div className="pip-row">
            {Array.from({length: SLOT_CAPACITY}).map((_,i) => (
              <span key={i} className={"pip" + (i < s.taken ? " taken" : "")}/>
            ))}
          </div>
        </button>
      ))}
    </div>
  );
}

function SlotsSchedule({ slots, onPick }) {
  const byHour = {};
  slots.forEach(s => { (byHour[s.hour] = byHour[s.hour] || []).push(s); });
  const hours = Object.keys(byHour).map(Number).sort((a,b)=>a-b);
  return (
    <div className="slots-schedule">
      {hours.map(h => (
        <React.Fragment key={h}>
          <div className="hour-cell">{String(h).padStart(2,"0")}:00</div>
          <div className="hour-slots">
            {byHour[h].map(s => (
              <button key={s.id} className={"sched-slot" + (s.full ? " is-full" : "")}
                      onClick={() => !s.full && onPick(s)} disabled={s.full}>
                <div className="t">{s.start}</div>
                <div className="sched-availability">
                  {s.full ? "Ausgebucht" : `${s.free} von ${SLOT_CAPACITY} frei`}
                </div>
                <div className="seats">
                  {Array.from({length: SLOT_CAPACITY}).map((_,i) => (
                    <span key={i} className={"seat" + (i < s.taken ? " filled" : "")}/>
                  ))}
                </div>
              </button>
            ))}
          </div>
        </React.Fragment>
      ))}
    </div>
  );
}

// ---------- BOOKING FORM ----------
function BookingForm({ slot, onSubmit, onChangeSlot, submitError }) {
  const [name, setName] = useState("");
  const [email, setEmail] = useState("");
  const [phone, setPhone] = useState("");
  const [firstTime, setFirstTime] = useState(null);
  const [consent, setConsent] = useState(false);
  const [errors, setErrors] = useState({});

  function validate() {
    const e = {};
    if (name.trim().length < 2) e.name = "Bitte vollständigen Namen angeben.";
    if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) e.email = "Gültige E-Mail-Adresse erforderlich.";
    if (phone.replace(/\D/g, "").length < 6) e.phone = "Bitte Telefonnummer angeben.";
    if (firstTime === null) e.firstTime = "Bitte auswählen.";
    if (!consent) e.consent = "Bitte zustimmen.";
    setErrors(e);
    return Object.keys(e).length === 0;
  }

  function submit(ev) {
    ev.preventDefault();
    if (!validate()) return;
    onSubmit({ name: name.trim(), email: email.trim(), phone: phone.trim(), firstTime });
  }

  return (
    <div className="view view-narrow" data-screen-label="03 Anmeldung">
      <span className="eyebrow"><span className="dot"></span>Schritt 2 von 3</span>
      <h2 style={{fontFamily: "Instrument Serif, Georgia, serif", fontWeight: 400, fontSize: 36, letterSpacing: "-0.02em", margin: "12px 0 8px"}}>Deine Anmeldung</h2>
      <p style={{color: "var(--ink-soft)", fontSize: 15, margin: 0}}>
        Wir brauchen nur ein paar Angaben für die Bestätigung und damit wir dich am Stand finden.
      </p>

      <form onSubmit={submit} className="form-card" noValidate>
        <div className="summary-strip">
          <span className="when">
            <b>{slot.start} – {slot.end}</b> · {ACTION_INFO.dateLabel}
          </span>
          <button type="button" onClick={onChangeSlot}>ändern</button>
        </div>

        <div className="field">
          <label>Vollständiger Name</label>
          <input type="text" value={name} onChange={e=>setName(e.target.value)} autoComplete="name" placeholder="Vor- und Nachname"/>
          <div className="err">{errors.name || ""}</div>
        </div>

        <div className="field">
          <label>E-Mail</label>
          <input type="email" value={email} onChange={e=>setEmail(e.target.value)} autoComplete="email" placeholder="vorname.nachname@cbes-lollar.de"/>
          <div className="err">{errors.email || ""}</div>
        </div>

        <div className="field">
          <label>Telefonnummer</label>
          <input type="tel" value={phone} onChange={e=>setPhone(e.target.value)} autoComplete="tel" placeholder="+49 …"/>
          <div className="err">{errors.phone || ""}</div>
        </div>

        <div className="field">
          <label>Hast du schon einmal Blut gespendet?</label>
          <div className="toggle-row">
            <button type="button" className={firstTime === false ? "active" : ""} onClick={()=>setFirstTime(false)}>
              <span>Ja, schon einmal</span>
              <span className="sub">Routinespende</span>
            </button>
            <button type="button" className={firstTime === true ? "active" : ""} onClick={()=>setFirstTime(true)}>
              <span>Nein, das erste Mal</span>
              <span className="sub">Erstspender:in</span>
            </button>
          </div>
          <div className="err">{errors.firstTime || ""}</div>
        </div>

        <label className="consent">
          <input type="checkbox" checked={consent} onChange={e=>setConsent(e.target.checked)}/>
          <span>
            Ich bin einverstanden, dass meine Angaben zur Organisation der Blutspendeaktion gespeichert, gemäß DSGVO verarbeitet und nach der Veranstaltung gelöscht werden. <span style={{color: "var(--accent)"}}>{errors.consent}</span>
          </span>
        </label>

        {submitError && (
          <div className="err" style={{marginTop: 8, padding: "10px 12px", background: "rgba(180, 30, 30, 0.06)", border: "1px solid rgba(180,30,30,0.2)", borderRadius: 8}}>
            {submitError}
          </div>
        )}

        <button type="submit" className="btn btn-accent btn-block">
          Termin verbindlich buchen
        </button>
      </form>
    </div>
  );
}

// ---------- CONFIRMATION ----------
function Confirmation({ booking, slot, onAnother, onHome }) {
  return (
    <div className="view view-narrow" data-screen-label="04 Bestaetigung">
      <div className="confirm-hero">
        <div className="confirm-mark" aria-hidden="true"/>
        <span className="eyebrow"><span className="dot"></span>Buchung bestätigt</span>
        <h2 style={{fontFamily: "Instrument Serif, Georgia, serif", fontWeight: 400, fontSize: 40, letterSpacing: "-0.02em", margin: "12px 0 6px"}}>
          Danke, {booking.name.split(" ")[0]}.
        </h2>
        <p style={{color: "var(--ink-soft)", fontSize: 15, margin: 0}}>
          Wir freuen uns auf dich.
        </p>
      </div>

      <div className="ticket">
        <div className="ticket-head">
          <span className="num">Buchung · {booking.id.toUpperCase()}</span>
          <span className="num">{ACTION_INFO.title}</span>
        </div>
        <div className="ticket-body">
          <div>
            <span className="lbl">Datum</span>
            <div className="big">12. Mai</div>
            <div style={{color:"var(--ink-soft)", fontSize: 13}}>Dienstag, 2026</div>
          </div>
          <div>
            <span className="lbl">Uhrzeit</span>
            <div className="big">{slot.start}</div>
            <div style={{color:"var(--ink-soft)", fontSize: 13, fontFamily:"JetBrains Mono, monospace"}}>bis {slot.end}</div>
          </div>
          <div style={{gridColumn:"1 / -1", borderTop: "1px dashed var(--line)", paddingTop: 16}}>
            <span className="lbl">Ort</span>
            <div style={{fontSize: 16, marginTop: 4}}>{ACTION_INFO.location}</div>
            <div style={{color:"var(--ink-soft)", fontSize: 13}}>{ACTION_INFO.address}</div>
          </div>
        </div>
        <div className="ticket-actions">
          <button className="btn btn-primary" onClick={() => downloadICS(booking, slot)}>
            ↓ Zum Kalender hinzufügen (.ics)
          </button>
          <button className="btn btn-ghost" onClick={onAnother}>
            Weitere Person anmelden
          </button>
        </div>
      </div>

      <div className="tips">
        <h4>Bis Dienstag</h4>
        <ul>
          <li>Genug trinken – mind. 1,5&thinsp;Liter Wasser oder Tee am Spendentag.</li>
          <li>Etwas essen – idealerweise ein vollständiges, leichtes Frühstück.</li>
          <li>Personalausweis nicht vergessen.</li>
          <li>Kein intensiver Sport in den 12 Stunden davor.</li>
        </ul>
      </div>

      <div style={{marginTop: 32, textAlign: "center"}}>
        <button onClick={onHome} className="btn btn-ghost">Zur Startseite</button>
      </div>
    </div>
  );
}

// ---------- ADMIN GATE ----------
function AdminGate({ onAuth }) {
  const [pw, setPw] = useState("");
  const [err, setErr] = useState("");
  const [busy, setBusy] = useState(false);

  async function submit(e) {
    e.preventDefault();
    if (busy) return;
    setBusy(true);
    setErr("");
    try {
      const token = await apiAdminLogin(pw);
      if (token) onAuth(token);
      else setErr("Passwort nicht korrekt.");
    } catch (e2) {
      setErr("Server nicht erreichbar. Bitte später erneut versuchen.");
    } finally {
      setBusy(false);
    }
  }

  return (
    <div className="gate" data-screen-label="05 Admin Login">
      <div className="gate-card">
        <span className="eyebrow"><span className="dot"></span>Verwaltung</span>
        <h2 style={{marginTop: 8}}>Anmeldung Leitung</h2>
        <p>Übersicht aller Buchungen, Filter, Sortierung und Check-in.</p>
        <form onSubmit={submit}>
          <div className="field">
            <label>Passwort</label>
            <input type="password" value={pw} onChange={e=>{setPw(e.target.value); setErr("");}} autoFocus/>
            <div className="err">{err}</div>
          </div>
          <button className="btn btn-primary btn-block" type="submit" disabled={busy}>{busy ? "Prüfe…" : "Einloggen"}</button>
        </form>
        <div className="hint">Zugang nur für die Aktionsleitung.</div>
      </div>
    </div>
  );
}

// ---------- ADMIN TABLE ----------
function AdminView({ bookings, onToggleCheckin, onDelete, apiOnline, onRefresh, onLogout }) {
  const [tab, setTab] = useState("calendar"); // calendar | table
  const [search, setSearch] = useState("");
  const [filter, setFilter] = useState("all");
  const [sortBy, setSortBy] = useState("slot");
  const [sortDir, setSortDir] = useState("asc");
  const [hoverBooking, setHoverBooking] = useState(null);

  const slotMap = useMemo(() => {
    const m = {};
    ALL_SLOTS.forEach(s => m[s.id] = s);
    return m;
  }, []);

  const filtered = useMemo(() => {
    let list = bookings.map(b => ({ ...b, slot: slotMap[b.slotId] }));
    if (search.trim()) {
      const q = search.toLowerCase();
      list = list.filter(b =>
        b.name.toLowerCase().includes(q) ||
        b.email.toLowerCase().includes(q) ||
        b.phone.includes(q)
      );
    }
    if (filter === "morning") list = list.filter(b => b.slot.hour < 12);
    if (filter === "afternoon") list = list.filter(b => b.slot.hour >= 12);
    if (filter === "first") list = list.filter(b => b.firstTime);
    if (filter === "checkedin") list = list.filter(b => b.checkedIn);

    list.sort((a,b) => {
      let av, bv;
      if (sortBy === "slot") { av = a.slotId; bv = b.slotId; }
      else if (sortBy === "name") { av = a.name; bv = b.name; }
      else if (sortBy === "email") { av = a.email; bv = b.email; }
      else if (sortBy === "phone") { av = a.phone; bv = b.phone; }
      else if (sortBy === "created") { av = a.createdAt; bv = b.createdAt; }
      else if (sortBy === "first") { av = a.firstTime ? 1 : 0; bv = b.firstTime ? 1 : 0; }
      else if (sortBy === "checked") { av = a.checkedIn ? 1 : 0; bv = b.checkedIn ? 1 : 0; }
      if (av < bv) return sortDir === "asc" ? -1 : 1;
      if (av > bv) return sortDir === "asc" ? 1 : -1;
      return 0;
    });
    return list;
  }, [bookings, search, filter, sortBy, sortDir, slotMap]);

  function toggleSort(col) {
    if (sortBy === col) setSortDir(d => d === "asc" ? "desc" : "asc");
    else { setSortBy(col); setSortDir("asc"); }
  }

  function toggleCheckin(id) {
    onToggleCheckin(id);
  }

  function deleteBooking(b) {
    const ok = window.confirm(
      `Buchung wirklich löschen?\n\n${b.name}\n${b.slot.start} – ${b.slot.end}\n${b.email}\n\nDieser Vorgang kann nicht rückgängig gemacht werden.`
    );
    if (ok) onDelete(b.id);
  }

  function exportCSV() {
    const rows = [
      ["ID","Zeit","Name","E-Mail","Telefon","Erstspender","Gebucht","Eingecheckt"],
      ...filtered.map(b => [
        b.id,
        `${b.slot.start} – ${b.slot.end}`,
        b.name,
        b.email,
        b.phone,
        b.firstTime ? "ja" : "nein",
        new Date(b.createdAt).toLocaleString("de-DE"),
        b.checkedIn ? "ja" : "nein",
      ])
    ];
    const csv = rows.map(r => r.map(v => `"${String(v).replace(/"/g,'""')}"`).join(";")).join("\n");
    const blob = new Blob(["\ufeff"+csv], { type: "text/csv;charset=utf-8" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url; a.download = `buchungen-${ACTION_DATE}.csv`;
    document.body.appendChild(a); a.click(); document.body.removeChild(a);
    setTimeout(()=>URL.revokeObjectURL(url), 1000);
  }

  const stats = {
    total: bookings.length,
    checkedIn: bookings.filter(b => b.checkedIn).length,
    firstTime: bookings.filter(b => b.firstTime).length,
    capacity: ALL_SLOTS.length * SLOT_CAPACITY,
  };

  function arrow(col) {
    if (sortBy !== col) return <span className="sort" style={{opacity: 0.25}}>↕</span>;
    return <span className="sort">{sortDir === "asc" ? "↑" : "↓"}</span>;
  }

  // Calendar grouping
  const calendarRows = useMemo(() => {
    return ALL_SLOTS.map(s => {
      const slotBookings = bookings.filter(b => b.slotId === s.id);
      return { slot: s, bookings: slotBookings };
    });
  }, [bookings]);

  return (
    <div className="admin-shell" data-screen-label="06 Admin Dashboard">
      <div className="admin-head">
        <div>
          <span className="eyebrow"><span className="dot"></span>Verwaltung · {ACTION_INFO.dateLabel}</span>
          <h2>Buchungsübersicht</h2>
        </div>
        <div className="admin-stats">
          <div className="stat"><div className="v">{stats.total}<span style={{color:"var(--ink-faint)", fontSize: 13}}> / {stats.capacity}</span></div><div className="l">Buchungen</div></div>
          <div className="stat"><div className="v">{stats.checkedIn}</div><div className="l">Eingecheckt</div></div>
          <div className="stat"><div className="v">{stats.firstTime}</div><div className="l">Erstspender</div></div>
          <div className="stat"><div className="v">{Math.round((stats.total/stats.capacity)*100)}%</div><div className="l">Auslastung</div></div>
        </div>
      </div>

      <div className="admin-tabs">
        <button className={tab==="calendar"?"active":""} onClick={()=>setTab("calendar")}>📅 Kalender</button>
        <button className={tab==="table"?"active":""} onClick={()=>setTab("table")}>📋 Tabelle</button>
        <div style={{flex:1}}/>
        <button className="btn btn-ghost" style={{padding:"8px 16px", fontSize: 13}} onClick={exportCSV}>↓ CSV</button>
        <button className="btn btn-ghost" style={{padding:"8px 16px", fontSize: 13}} onClick={onLogout}>Logout</button>
      </div>

      {tab === "calendar" && (
        <div className="cal-wrap">
          <div className="cal-legend">
            <span><i className="leg-dot leg-empty"/>frei</span>
            <span><i className="leg-dot leg-some"/>teilweise belegt</span>
            <span><i className="leg-dot leg-full"/>ausgebucht</span>
            <span><i className="leg-dot leg-checked"/>eingecheckt</span>
          </div>
          <div className="cal-grid">
            <div className="cal-head">
              <div className="cal-time-col">Uhrzeit</div>
              {Array.from({length: SLOT_CAPACITY}).map((_,i) => (
                <div key={i} className="cal-seat-col">Platz {i+1}</div>
              ))}
            </div>
            {calendarRows.map(({slot, bookings: bs}) => {
              const free = SLOT_CAPACITY - bs.length;
              const allChecked = bs.length > 0 && bs.every(b => b.checkedIn);
              const status = bs.length === 0 ? "empty" : allChecked ? "checked" : free === 0 ? "full" : "some";
              return (
                <div key={slot.id} className={"cal-row cal-row-"+status}>
                  <div className="cal-time-col">
                    <b>{slot.start}</b>
                    <span className="cal-time-end">– {slot.end}</span>
                  </div>
                  {Array.from({length: SLOT_CAPACITY}).map((_,i) => {
                    const b = bs[i];
                    if (!b) return <div key={i} className="cal-cell cal-cell-empty">frei</div>;
                    return (
                      <div
                        key={i}
                        className={"cal-cell cal-cell-booked" + (b.checkedIn ? " checked" : "") + (b.firstTime ? " first" : "")}
                        onMouseEnter={()=>setHoverBooking(b)}
                        onMouseLeave={()=>setHoverBooking(null)}
                        onClick={()=>toggleCheckin(b.id)}
                        title="Klick: Check-in umschalten"
                      >
                        <div className="cal-name">{b.name}</div>
                        <div className="cal-tags">
                          {b.firstTime && <span className="mini-tag">1.</span>}
                          {b.checkedIn && <span className="mini-tag check">✓</span>}
                        </div>
                      </div>
                    );
                  })}
                </div>
              );
            })}
          </div>
          {hoverBooking && (
            <div className="cal-hint">
              <b>{hoverBooking.name}</b> · {hoverBooking.email} · {hoverBooking.phone}
              {hoverBooking.firstTime && " · Erstspender:in"}
            </div>
          )}
        </div>
      )}

      {tab === "table" && (
        <>
          <div className="admin-toolbar">
            <div className="search-box">
              <span style={{color:"var(--ink-faint)"}}>⌕</span>
              <input placeholder="Name, E-Mail, Telefon…" value={search} onChange={e=>setSearch(e.target.value)}/>
            </div>
            <div className="chip-group">
              <button className={filter==="all"?"active":""} onClick={()=>setFilter("all")}>Alle</button>
              <button className={filter==="morning"?"active":""} onClick={()=>setFilter("morning")}>Vormittag</button>
              <button className={filter==="afternoon"?"active":""} onClick={()=>setFilter("afternoon")}>Nachmittag</button>
              <button className={filter==="first"?"active":""} onClick={()=>setFilter("first")}>Erstspender</button>
              <button className={filter==="checkedin"?"active":""} onClick={()=>setFilter("checkedin")}>Eingecheckt</button>
            </div>
            <div style={{flex: 1}}/>
            <span style={{fontFamily:"JetBrains Mono, monospace", fontSize: 11, color:"var(--ink-faint)", letterSpacing:"0.05em", textTransform:"uppercase"}}>
              {filtered.length} {filtered.length === 1 ? "Eintrag" : "Einträge"}
            </span>
          </div>

          <div className="xl-wrap">
            {filtered.length === 0 ? (
              <div className="empty">
                <div className="em-mark">∅</div>
                <div>Keine Buchungen passen zum Filter.</div>
              </div>
            ) : (
              <table className="xl-table">
                <thead>
                  <tr>
                    <th className="rownum"></th>
                    <th onClick={()=>toggleSort("slot")} style={{width:110}}>Zeit {arrow("slot")}</th>
                    <th onClick={()=>toggleSort("name")}>Name {arrow("name")}</th>
                    <th onClick={()=>toggleSort("email")}>E-Mail {arrow("email")}</th>
                    <th onClick={()=>toggleSort("phone")} style={{width:160}}>Telefon {arrow("phone")}</th>
                    <th onClick={()=>toggleSort("first")} style={{width:120}}>Status {arrow("first")}</th>
                    <th onClick={()=>toggleSort("created")} style={{width:130}}>Gebucht {arrow("created")}</th>
                    <th onClick={()=>toggleSort("checked")} style={{width:120}}>Check-in {arrow("checked")}</th>
                    <th style={{width:60}}></th>
                  </tr>
                </thead>
                <tbody>
                  {filtered.map((b, idx) => (
                    <tr key={b.id}>
                      <td className="rownum" data-label="#">{idx + 1}</td>
                      <td className="t" data-label="Zeit">{b.slot.start}<span style={{color:"var(--ink-faint)"}}> – {b.slot.end}</span></td>
                      <td data-label="Name"><b>{b.name}</b></td>
                      <td data-label="E-Mail" className="cell-email">{b.email}</td>
                      <td data-label="Telefon" className="cell-phone">{b.phone}</td>
                      <td data-label="Status">
                        {b.firstTime
                          ? <span className="tag first">Erstspender</span>
                          : <span className="tag">Routine</span>}
                      </td>
                      <td className="t cell-created" data-label="Gebucht">
                        {new Date(b.createdAt).toLocaleDateString("de-DE", {day:"2-digit",month:"2-digit"})}
                        {" "}
                        {new Date(b.createdAt).toLocaleTimeString("de-DE", {hour:"2-digit",minute:"2-digit"})}
                      </td>
                      <td data-label="Check-in">
                        <button
                          className={"checkbtn" + (b.checkedIn ? " checked" : "")}
                          onClick={()=>toggleCheckin(b.id)}>
                          {b.checkedIn ? "✓ anwesend" : "markieren"}
                        </button>
                      </td>
                      <td data-label="" className="cell-delete">
                        <button
                          className="deletebtn"
                          onClick={()=>deleteBooking(b)}
                          title="Buchung löschen"
                          aria-label={`Buchung von ${b.name} löschen`}>
                          ✕
                        </button>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            )}
          </div>
        </>
      )}
    </div>
  );
}

// ---------- COOKIE / DSGVO BANNER ----------
function CookieBanner() {
  const [shown, setShown] = useState(() => !localStorage.getItem("cookies.consent.v1"));
  const [showDetails, setShowDetails] = useState(false);

  function accept() {
    localStorage.setItem("cookies.consent.v1", JSON.stringify({ choice: "accept", at: new Date().toISOString() }));
    setShown(false);
  }
  function decline() {
    localStorage.setItem("cookies.consent.v1", JSON.stringify({ choice: "decline", at: new Date().toISOString() }));
    setShown(false);
  }

  if (!shown) return null;

  return (
    <div className="cookie-banner" role="dialog" aria-labelledby="cookie-title">
      <div className="cookie-inner">
        <div className="cookie-text">
          <h3 id="cookie-title">Datenschutz & Cookies</h3>
          <p>
            Gespeicherte Daten (Name, E-Mail, Telefon) werden ausschließlich zur Organisation
            der Blutspendeaktion verwendet, nach der Veranstaltung gelöscht und gemäß
            EU-Datenschutzstandards (DSGVO) verarbeitet. Kein Tracking, keine Weitergabe an Dritte.
          </p>
          {showDetails && (
            <ul className="cookie-list">
              <li><b>cookies.consent.v1</b> — deine Einwilligungsentscheidung (1 Jahr, lokal)</li>
              <li><b>Buchungsdaten</b> — serverseitig, Löschung nach der Veranstaltung</li>
            </ul>
          )}
          <button className="cookie-detail-toggle" onClick={()=>setShowDetails(s => !s)}>
            {showDetails ? "Weniger anzeigen" : "Details anzeigen"}
          </button>
        </div>
        <div className="cookie-actions">
          <button className="btn btn-ghost cookie-decline" onClick={decline}>
            Nur notwendige
          </button>
          <button className="btn btn-accent cookie-accept" onClick={accept}>
            Verstanden & einverstanden
          </button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Landing, LandingModern, LandingBold, SlotPicker, BookingForm, Confirmation, AdminGate, AdminView, CookieBanner });
