/* Lieblingsmarken — Community-Empfehlungen für nachhaltige Mode
   Reine Frontend-Demo. Brand-Style: minimalismuse (Creme, Anthrazit, Senf, Pfirsich, Montserrat). */
const { useState, useMemo, useEffect, useRef } = React;

/* ─── Beispieldaten ─────────────────────────────────────────── */
const SEED = [
  {
    name: "ARMEDANGELS",
    cats: ["Jeans", "Allerlei"],
    votes: [
      { t: "nachhaltigere Kleidung", kind: "pro" },
      { t: "inzwischen viele Kollektionen, kein slow fashion mehr", kind: "hint" },
    ],
  },
  {
    name: "Dilling",
    cats: ["Basics", "Sport BHs", "Kinderkleidung"],
    votes: [
      { t: "mulesing-freie Merinowolle", kind: "pro" },
      { t: "sehr gutes Preisleistungsverhältnis", kind: "pro" },
      { t: "Ripp Oberteile leiern aus, andere halten gut", kind: "hint" },
    ],
  },
  {
    name: "OSKA",
    cats: ["Hosen", "Allerlei"],
    votes: [
      { t: "zeitlose Slow Fashion", kind: "pro" },
      { t: "hochpreisig, aber die Qualität wert", kind: "hint" },
      { t: "sehr bequeme und schöne Hosen", kind: "pro" },
    ],
  },
  {
    name: "The Slow Label",
    cats: ["Basics", "Tops"],
    votes: [
      { t: "die besten Tops", kind: "pro" },
      { t: "blickdicht ohne BH", kind: "pro" },
      { t: "leider häufig ausverkauft", kind: "hint" },
    ],
  },
];

/* Fallback-Zähler, wenn keine API-Daten da sind: Anzahl O-Töne */
const withCount = (b) => ({ ...b, count: b.votes.length });

/* Vollständige Kategorienliste (Stand Notion-Schema) — für das Einreichen-Formular,
   damit auch neue Marken passend eingeordnet werden können. Die Filter-Chips oben
   nutzen dagegen die vom Backend gelieferten, tatsächlich vorhandenen Kategorien. */
const CATEGORIES = [
  "Allerlei", "Jeans", "Hosen", "Unterwäsche", "Schuhe", "Yoga Wear",
  "Kinderkleidung", "Basics", "Tops", "Langarmoberteile", "Sport BHs",
  "Strickjacken", "Pullover", "Hausschuhe", "Westen", "Handschuhe",
  "Activewear", "Leggins", "Hijabs",
];

const LOGO = "assets/libelle.png";

/* ─── Kleine Bausteine ──────────────────────────────────────── */
function Logo({ size = 30 }) {
  return <img src={LOGO} alt="Lieblingsmarken" className="logo" style={{ width: size, height: size }} />;
}

function Chip({ label, active, onClick, small }) {
  return (
    <button
      type="button"
      className={"chip" + (active ? " chip--on" : "") + (small ? " chip--sm" : "")}
      onClick={onClick}
    >
      {label}
    </button>
  );
}

/* ─── Marken-Karte ──────────────────────────────────────────── */
function BrandCard({ brand, open, onToggle, isNew }) {
  const bodyRef = useRef(null);
  const [h, setH] = useState(0);
  useEffect(() => {
    if (bodyRef.current) setH(open ? bodyRef.current.scrollHeight : 0);
  }, [open, brand]);

  return (
    <article className={"card" + (open ? " card--open" : "") + (isNew ? " card--new" : "")}>
      <button type="button" className="card__head" onClick={onToggle} aria-expanded={open}>
        <div className="card__title">
          <h3>{brand.name}</h3>
          {brand.slogan ? <p className="card__slogan">{brand.slogan}</p> : null}
          <div className="card__cats">
            {(open ? brand.cats : brand.cats.slice(0, 2)).map((c) => (
              <span key={c} className="tag">{c}</span>
            ))}
            {!open && brand.cats.length > 2 ? (
              <span className="tag tag--more">+{brand.cats.length - 2}</span>
            ) : null}
          </div>
        </div>
        <div className="card__meta">
          <span className="count" title={brand.count === 1 ? "1 Empfehlung" : brand.count + " Empfehlungen"}>
            <span className="count__pill">
              <svg className="count__heart" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
                <path d="M12 21l-1.45-1.32C5.4 14.36 2 11.28 2 7.5 2 4.42 4.42 2 7.5 2c1.74 0 3.41.81 4.5 2.09C13.09 2.81 14.76 2 16.5 2 19.58 2 22 4.42 22 7.5c0 3.78-3.4 6.86-8.55 11.18L12 21z" />
              </svg>
              {brand.count}
            </span>
          </span>
          <span className="chev" aria-hidden="true">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
              <path d="M4 6l4 4 4-4" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
          </span>
        </div>
      </button>

      <div className="card__reveal" style={{ height: h }}>
        <div className="card__body" ref={bodyRef}>
          <p className="card__body-label">O-Töne aus der Community</p>
          <ul className="voices">
            {brand.votes.map((v, i) => (
              <li key={i} className={"voice voice--" + v.kind}>
                <span className="voice__dot" aria-hidden="true" />
                <span className="voice__text">{v.t}</span>
              </li>
            ))}
          </ul>
          {brand.website ? (
            <a className="card__shop" href={brand.website} target="_blank" rel="noopener noreferrer">
              Zum Shop
              <svg width="13" height="13" viewBox="0 0 14 14" fill="none" aria-hidden="true">
                <path d="M4.5 9.5l5-5M5.5 4.5h4v4" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round" />
              </svg>
            </a>
          ) : null}
        </div>
      </div>
    </article>
  );
}

/* ─── Einreichen-Formular (Modal) ───────────────────────────── */
function SubmitSheet({ onClose, onSubmit }) {
  const [name, setName] = useState("");
  const [cats, setCats] = useState([]);
  const [note, setNote] = useState("");
  const [done, setDone] = useState(false);
  const [sending, setSending] = useState(false);
  const [err, setErr] = useState("");

  const toggleCat = (c) =>
    setCats((p) => (p.includes(c) ? p.filter((x) => x !== c) : [...p, c]));

  const canSend = name.trim().length > 1 && cats.length > 0 && note.trim().length > 1;

  const send = async () => {
    if (!canSend || sending) return;
    setSending(true);
    setErr("");
    try {
      await onSubmit({ name: name.trim(), cats, votes: [{ t: note.trim(), kind: "pro" }] });
      setDone(true);
    } catch (e) {
      setErr("Das hat gerade nicht geklappt. Bitte versuch es nochmal.");
    } finally {
      setSending(false);
    }
  };

  return (
    <div className="sheet-overlay" onClick={onClose}>
      <div className="sheet" onClick={(e) => e.stopPropagation()}>
        <button className="sheet__close" onClick={onClose} aria-label="Schließen">
          <svg width="18" height="18" viewBox="0 0 18 18"><path d="M4 4l10 10M14 4L4 14" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/></svg>
        </button>

        {done ? (
          <div className="sheet__thanks">
            <Logo size={40} />
            <h2>Danke, dass du teilst.</h2>
            <p className="muted">Deine Empfehlung wird kurz geprüft und erscheint dann in der Liste. Magst du noch eine teilen?</p>
            <button className="btn btn--ghost" onClick={onClose}>Zurück zur Übersicht</button>
          </div>
        ) : (
          <React.Fragment>
            <p className="eyebrow">Eigene Empfehlung teilen</p>
            <h2 className="sheet__h">Welche Marke trägst du gern?</h2>

            <label className="field">
              <span className="field__lbl">Marke</span>
              <input className="input" value={name} onChange={(e) => setName(e.target.value)} placeholder="z.B. ARMEDANGELS" />
            </label>

            <div className="field">
              <span className="field__lbl">Kategorien</span>
              <div className="chips chips--wrap">
                {CATEGORIES.map((c) => (
                  <Chip key={c} label={c} small active={cats.includes(c)} onClick={() => toggleCat(c)} />
                ))}
              </div>
            </div>

            <label className="field">
              <span className="field__lbl">Dein O-Ton</span>
              <textarea className="input input--area" value={note} onChange={(e) => setNote(e.target.value)} rows={3}
                placeholder="Was macht diese Marke für dich besonders?" />
            </label>

            <button className={"btn btn--cta" + (canSend && !sending ? "" : " btn--off")} onClick={send}>
              {sending ? "Wird gesendet …" : "Empfehlung teilen"}
            </button>
            {err ? <p className="field__err">{err}</p> : null}
            <p className="sheet__note muted">Sichtbar wird sie nach einer kurzen Prüfung. Du kannst sie jederzeit zurückziehen.</p>
          </React.Fragment>
        )}
      </div>
    </div>
  );
}

/* ─── Login-Ansicht ─────────────────────────────────────────── */
function LoginView({ onEnter }) {
  const [email, setEmail] = useState("");
  const [sent, setSent] = useState(false);
  const [err, setErr] = useState("");

  const valid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.trim());

  const submit = (e) => {
    e.preventDefault();
    if (!valid) { setErr("Bitte gib eine gültige E-Mail-Adresse ein."); return; }
    setErr("");
    setSent(true);
  };

  return (
    <div className="login">
      <div className="login__card">
        <Logo size={46} />
        {sent ? (
          <React.Fragment>
            <h1 className="login__h">Schau in dein Postfach.</h1>
            <p className="login__sub">
              Wir haben einen Login-Link an <strong>{email.trim()}</strong> geschickt.
              Klick ihn an, dann bist du drin.
            </p>
            <button className="btn btn--cta" onClick={onEnter}>Zur Community</button>
            <button className="linklike" onClick={() => setSent(false)}>Andere E-Mail verwenden</button>
          </React.Fragment>
        ) : (
          <React.Fragment>
            <p className="eyebrow">Lieblingsmarken</p>
            <h1 className="login__h">Schön, dass du da bist.</h1>
            <p className="login__sub">
              Gib deine E-Mail ein, wir schicken dir einen Login-Link. Kein Passwort, kein Aufwand.
            </p>
            <form onSubmit={submit} className="login__form" noValidate>
              <input
                className={"input" + (err ? " input--err" : "")}
                type="email"
                value={email}
                onChange={(e) => { setEmail(e.target.value); if (err) setErr(""); }}
                placeholder="deine@email.de"
                autoComplete="email"
              />
              {err ? <p className="field__err">{err}</p> : null}
              <button className="btn btn--cta" type="submit">Login-Link schicken</button>
            </form>
            <p className="login__fine muted">
              Eine geschlossene Community. Dein Zugang gehört zu deinem Kurs.
            </p>
          </React.Fragment>
        )}
      </div>
    </div>
  );
}

/* ─── Haupt-App ─────────────────────────────────────────────── */
function CommunityView() {
  const [brands, setBrands] = useState(null);   // null = lädt noch
  const [filterCats, setFilterCats] = useState(CATEGORIES); // Chips: vom Backend gefüllt
  const [active, setActive] = useState([]);   // gewählte Kategorien (ODER)
  const [q, setQ] = useState("");
  const [openName, setOpenName] = useState(null);
  const [sheet, setSheet] = useState(false);
  const [newName, setNewName] = useState(null);
  const [toast, setToast] = useState("");

  // Daten aus der API holen; bei Fehler (z.B. lokale Vorschau ohne Backend)
  // auf die Beispieldaten zurückfallen, damit die Ansicht nie leer bleibt.
  useEffect(() => {
    let alive = true;
    fetch("/api/brands")
      .then((r) => (r.ok ? r.json() : Promise.reject(r.status)))
      .then((data) => {
        if (!alive) return;
        setBrands((data.brands || []).map((b) => ({ ...b, votes: b.votes || [] })));
        if (data.categories && data.categories.length) setFilterCats(data.categories);
      })
      .catch(() => { if (alive) setBrands(SEED.map(withCount)); });
    return () => { alive = false; };
  }, []);

  const toggleCat = (c) =>
    setActive((p) => (p.includes(c) ? p.filter((x) => x !== c) : [...p, c]));

  const results = useMemo(() => {
    const needle = q.trim().toLowerCase();
    const isAllerlei = (b) => b.cats.some((c) => c.toLowerCase() === "allerlei");
    // "Allerlei"-Marken (führen von allem etwas) bleiben sichtbar, wenn nach einem
    // Kleidungsstück gefiltert/gesucht wird – nicht aber bei Schuhen, Unterwäsche etc.
    const APPAREL = [
      "hose", "hosen", "oberteil", "t-shirt", "tshirt", "top", "tops", "rock",
      "basics", "jeans", "langarmoberteil", "langarmoberteile", "strickjacke", "strickjacken",
    ];
    const allerleiKeep =
      active.some((c) => APPAREL.includes(c.toLowerCase())) ||
      (needle.length >= 2 && APPAREL.some((t) => t.includes(needle) || needle.includes(t)));
    return (brands || [])
      .filter((b) => active.length === 0 || b.cats.some((c) => active.includes(c)) || (allerleiKeep && isAllerlei(b)))
      .filter((b) => {
        if (!needle) return true;
        return (
          b.name.toLowerCase().includes(needle) ||
          b.cats.some((c) => c.toLowerCase().includes(needle)) ||
          b.votes.some((v) => v.t.toLowerCase().includes(needle)) ||
          (allerleiKeep && isAllerlei(b))
        );
      })
      .sort((a, b) => b.count - a.count);
  }, [brands, active, q]);

  const addBrand = async (data) => {
    // Erst nach Notion schreiben (Pending); die Art (Pro/Hinweis) wird später
    // automatisch per Sentiment bestimmt, darum hier nicht mitsenden.
    const res = await fetch("/api/submit", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ name: data.name, cats: data.cats, note: data.votes[0].t }),
    });
    if (!res.ok) {
      const info = await res.json().catch(() => ({}));
      throw new Error(info.error || "Speichern fehlgeschlagen");
    }

    // Optimistisch in dieser Sitzung anzeigen. Öffentlich erscheint sie erst
    // nach Freigabe (die API liefert nur Approved-Einträge).
    setBrands((prev) => {
      const p = prev || [];
      const existing = p.find((b) => b.name.toLowerCase() === data.name.toLowerCase());
      if (existing) {
        return p.map((b) =>
          b === existing
            ? { ...b, votes: [...b.votes, ...data.votes],
                cats: Array.from(new Set([...b.cats, ...data.cats])) }
            : b
        );
      }
      return [{ ...data, count: data.votes.length }, ...p];
    });
    setNewName(data.name);
    setToast("Danke! Deine Empfehlung wird geprüft.");
    setTimeout(() => setToast(""), 3200);
    setTimeout(() => setNewName(null), 2400);
  };

  return (
    <div className="app">
      {/* Kopf / Intro */}
      <header className="hdr">
        <div className="hdr__bar">
          <div className="brandmark">
            <Logo size={28} />
            <span className="brandmark__name">Lieblingsmarken</span>
          </div>
          <button className="linklike linklike--quiet" onClick={() => (window.location.search = "?view=login")}>
            Konto
          </button>
        </div>
        <div className="hdr__intro">
          <h1>Lieblingsmarken der <span className="pf">Miracle Wardrobe Community</span></h1>
          <p>Gesammelte Empfehlungen für nachhaltige Mode. Ehrlich, persönlich, von Frauen wie dir.</p>
        </div>
      </header>

      {/* Suche */}
      <div className="search">
        <svg className="search__ic" width="17" height="17" viewBox="0 0 17 17" fill="none">
          <circle cx="7.2" cy="7.2" r="5.2" stroke="currentColor" strokeWidth="1.3" />
          <path d="M11.2 11.2L15 15" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" />
        </svg>
        <input className="search__in" value={q} onChange={(e) => setQ(e.target.value)} placeholder="Marke oder Stichwort suchen" />
        {q ? <button className="search__clear" onClick={() => setQ("")} aria-label="Suche leeren">×</button> : null}
      </div>

      {/* Kategorie-Filter */}
      <div className="filters">
        <div className="chips chips--scroll">
          {filterCats.map((c) => (
            <Chip key={c} label={c} active={active.includes(c)} onClick={() => toggleCat(c)} />
          ))}
        </div>
        {active.length > 0 ? (
          <button className="linklike linklike--quiet filters__reset" onClick={() => setActive([])}>
            Filter zurücksetzen
          </button>
        ) : null}
      </div>

      {/* Ergebnis-Zeile */}
      <div className="resultline muted">
        {brands === null
          ? "lädt …"
          : results.length === brands.length
          ? `${brands.length} Marken`
          : `${results.length} von ${brands.length} Marken`}
      </div>

      {/* Marken-Übersicht */}
      <main className="list">
        {brands === null ? (
          <div className="empty">
            <Logo size={36} />
            <p className="muted">Einen Moment, die Marken werden geladen.</p>
          </div>
        ) : results.length === 0 ? (
          <div className="empty">
            <Logo size={36} />
            <p>Noch keine Marke in dieser Auswahl.</p>
            <p className="muted">Magst du die erste teilen, die hierher gehört?</p>
            <button className="btn btn--ghost" onClick={() => setSheet(true)}>Empfehlung teilen</button>
          </div>
        ) : (
          results.map((b) => (
            <BrandCard
              key={b.name}
              brand={b}
              open={openName === b.name}
              isNew={newName === b.name}
              onToggle={() => setOpenName((p) => (p === b.name ? null : b.name))}
            />
          ))
        )}
      </main>

      {/* Sticky CTA */}
      <div className="cta-bar">
        <button className="btn btn--cta btn--block" onClick={() => setSheet(true)}>
          Eigene Empfehlung teilen
        </button>
      </div>

      {toast ? <div className="toast">{toast}</div> : null}
      {sheet ? <SubmitSheet onClose={() => setSheet(false)} onSubmit={addBrand} /> : null}
    </div>
  );
}

/* ─── Root: wählt Ansicht ───────────────────────────────────── */
function App() {
  const params = new URLSearchParams(window.location.search);
  const [view, setView] = useState(params.get("view") === "login" ? "login" : "app");
  if (view === "login") return <LoginView onEnter={() => setView("app")} />;
  return <CommunityView />;
}

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