// ============================================================
// ui.jsx — wspólne komponenty: nawigacja, stopka, formularze,
// pełny przepływ głosowania (double opt-in + weryfikacja e-ID — symulacja)
// ============================================================

const { useState, useEffect, useRef } = React;

function navigate(path) { window.location.hash = "#" + path; if (path !== "/koncepcja" && path !== "/mapa") window.scrollTo(0, 0); }
function Link({ to, className, children, ...rest }) {
  return <a href={"#" + to} className={className} onClick={() => { if (to !== "/koncepcja" && to !== "/mapa") window.scrollTo(0, 0); }} {...rest}>{children}</a>;
}

// ---------- Toast ----------
let _toastFn = null;
function ToastHost() {
  const [msg, setMsg] = useState(null);
  useEffect(() => {
    _toastFn = (m) => { setMsg(m); clearTimeout(_toastFn._t); _toastFn._t = setTimeout(() => setMsg(null), 3200); };
    return () => { _toastFn = null; };
  }, []);
  if (!msg) return null;
  return <div className="toast"><span style={{ color: "var(--green)", fontWeight: 700 }}>✓</span>{msg}</div>;
}
function toast(m) { if (_toastFn) _toastFn(m); }

// ---------- Nawigacja ----------
function Nav({ route }) {
  const links = [
    ["/koncepcja", "Koncepcja"],
    ["/gminy", "Dla gmin"],
    ["/inwestorzy", "Dla inwestorów"],
    ["/kontakt", "Kontakt", "hide-m"],
  ];
  return (
    <nav className="nav">
      <div className="nav-inner">
        <Link to="/" className="nav-logo">
          <LogoMark />
          <span><LogoWordmark /><span style={{ color: "var(--ink-3)", fontWeight: 400 }} className="hide-m"> / budowle ochronne</span></span>
        </Link>
        <div className="nav-links">
          {links.map(([to, label, cls]) => (
            <Link key={to} to={to} className={"nav-link " + (cls || "") + (route.startsWith(to) ? " active" : "")}>{label}</Link>
          ))}
          <Link to="/mapa" className={"nav-link cta"}>Mapa i głosowanie</Link>
        </div>
      </div>
    </nav>
  );
}

// ---------- Stopka ----------
// ---------- Logo Park&Protect ----------
function LogoMark({ size = 26 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" style={{ flex: "none", display: "block" }}>
      {/* tarcza */}
      <path d="M13 1.5 L23.5 5.5 V13 C23.5 19 19.2 23.2 13 25 C6.8 23.2 2.5 19 2.5 13 V5.5 Z" fill="var(--ink)" />
      {/* liść — odzysk zieleni */}
      <path d="M13 20.5 C8.5 18.6 7.2 14.2 8.6 9.6 C13.4 10 17.4 12.4 17.4 16.6 C17.4 18.3 15.6 20.1 13 20.5 Z" fill="var(--green)" />
      <path d="M13 20.5 C11.6 16.4 11.4 13.2 12.6 10.4" stroke="#fff" strokeWidth="1.1" strokeLinecap="round" fill="none" />
    </svg>
  );
}

function LogoWordmark() {
  return (
    <span>Park<span style={{ color: "var(--green)" }}>&amp;</span>Protect</span>
  );
}

function Footer() {
  return (
    <footer className="footer">
      <div className="container">
        <div className="cols">
          <div style={{ maxWidth: 320 }}>
            <div style={{ display: "flex", alignItems: "center", gap: 10, fontWeight: 600, marginBottom: 8 }}><LogoMark size={22} /><LogoWordmark /></div>
            <p className="small muted">Sebastian Bogusz — mgr inż. arch., architekt IARP. Przygotowanie i eksploatacja schronów i ukryć dla ludności (WAT).</p>
          </div>
          <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
            <span className="kicker" style={{ color: "var(--ink-3)" }}>Platforma</span>
            <Link to="/mapa">Mapa lokalizacji</Link>
            <Link to="/zglos">Zaproponuj lokalizację</Link>
            <Link to="/moje">Moje głosy i propozycje</Link>
            <Link to="/admin">Panel administracyjny</Link>
          </div>
          <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
            <span className="kicker" style={{ color: "var(--ink-3)" }}>Informacje</span>
            <Link to="/kontakt">Kontakt</Link>
            <Link to="/polityka-prywatnosci">Polityka prywatności</Link>
            <Link to="/regulamin">Regulamin platformy</Link>
          </div>
        </div>
        <div className="small" style={{ marginTop: 32, paddingTop: 20, borderTop: "1px solid var(--line)", color: "var(--ink-3)", display: "flex", gap: 18, flexWrap: "wrap" }}>
          <span>© 2026 Park&amp;Protect · Sebastian Bogusz</span>
          <span>Dane mapowe: © OpenStreetMap contributors</span>
          <span>Ortofotomapa: Geoportal.gov.pl / GUGiK</span>
        </div>
      </div>
    </footer>
  );
}

// ---------- Modal ----------
function Modal({ onClose, children, width }) {
  return (
    <div className="modal-backdrop" onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="modal" style={width ? { maxWidth: width } : null}>{children}</div>
    </div>
  );
}

// ---------- Fake Turnstile ----------
function Turnstile({ ok, onOk }) {
  const [busy, setBusy] = useState(false);
  return (
    <div className={"turnstile" + (ok ? " ok" : "")} onClick={() => {
      if (ok || busy) return;
      setBusy(true);
      setTimeout(() => { setBusy(false); onOk(); }, 700);
    }}>
      <div className="box">{ok ? "✓" : busy ? <span style={{ width: 10, height: 10, border: "2px solid var(--accent)", borderTopColor: "transparent", borderRadius: 99, display: "block", animation: "spin 0.7s linear infinite" }}></span> : ""}</div>
      <div>
        <div style={{ fontSize: 13, fontWeight: 600 }}>{ok ? "Zweryfikowano" : "Potwierdź, że nie jesteś robotem"}</div>
        <div style={{ fontSize: 10.5, color: "var(--ink-3)", fontFamily: "var(--font-mono)" }}>Cloudflare Turnstile</div>
      </div>
    </div>
  );
}

// ---------- Disclaimer ----------
function Disclaimer() {
  return (
    <p className="small" style={{ color: "var(--ink-3)", fontSize: 12, lineHeight: 1.5 }}>
      Deklaracja ma charakter niewiążącego badania zainteresowania. Nie stanowi oferty,
      rezerwacji ani zobowiązania. Nie przyjmujemy żadnych wpłat.
    </p>
  );
}

// ---------- Liczniki głosów ----------
function VoteCounter({ locId, size }) {
  useStore();
  const v = votesFor(locId);
  const big = size === "lg";
  return (
    <div style={{ display: "flex", alignItems: "baseline", gap: 10 }}>
      <span className="stat-num" style={{ fontSize: big ? 34 : 20 }}>{fmt(v.total)}</span>
      <span className="muted" style={{ fontSize: big ? 15 : 13 }}>głosów</span>
      <span className="badge green" title="Głosy zweryfikowane tożsamością (mojeID / mObywatel)">✓ {fmt(v.verified)} zweryfikowanych</span>
    </div>
  );
}

function VoteDistribution({ locId }) {
  useStore();
  const v = votesFor(locId);
  if (!v.total) return <p className="small muted">Brak potwierdzonych głosów — bądź pierwszy.</p>;
  const pct = (n) => (100 * n / v.total) + "%";
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
      <div className="distbar">
        <div className="buy" style={{ width: pct(v.buy) }}></div>
        <div className="rent" style={{ width: pct(v.rent) }}></div>
        <div className="support" style={{ width: pct(v.support) }}></div>
      </div>
      <div className="legend">
        <span><span className="dot" style={{ background: "var(--accent)" }}></span>kupno · {v.buy}</span>
        <span><span className="dot" style={{ background: "oklch(65% 0.09 252)" }}></span>najem · {v.rent}</span>
        <span><span className="dot" style={{ background: "var(--green)" }}></span>poparcie · {v.support}</span>
      </div>
    </div>
  );
}

// ============================================================
// Przepływ głosowania:
// form → wysłany e-mail (symulacja) → potwierdzono → upsell e-ID → ✓
// ============================================================
function VoteFlow({ loc, onDone, compact }) {
  const s = useStore();
  const already = s.myVotes.find((v) => v.locId === loc.id && !v.withdrawn);
  const [stage, setStage] = useState(already ? (already.verified ? "verified" : "confirmed") : "form");
  const [interest, setInterest] = useState("support");
  const [priceBand, setPriceBand] = useState("");
  const [email, setEmail] = useState("");
  const [rodo, setRodo] = useState(false);
  const [contact, setContact] = useState(false);
  const [ts, setTs] = useState(false);
  const [err, setErr] = useState(null);
  const [idModal, setIdModal] = useState(null); // 'mojeid' | 'mobywatel'

  const submit = () => {
    if (!/.+@.+\..+/.test(email)) return setErr("Podaj prawidłowy adres e-mail.");
    if (!rodo) return setErr("Zgoda na przetwarzanie danych jest wymagana.");
    if (!ts) return setErr("Potwierdź weryfikację antybotową.");
    setErr(null);
    setStage("sent");
  };

  const confirmEmail = () => {
    Store.set({ myVotes: [...Store.get().myVotes, { locId: loc.id, interest, priceBand, verified: false, email, ts: Date.now() }] });
    Store.audit("system", "confirm_email", "declaration", { loc: loc.slug });
    setStage("confirmed");
    toast("Głos potwierdzony i doliczony do agregatów");
  };

  const verify = (method) => {
    setIdModal(null);
    const votes = Store.get().myVotes.map((v) => v.locId === loc.id ? { ...v, verified: true, method } : v);
    Store.set({ myVotes: votes });
    Store.audit("system", "identity_verified", "declaration", { loc: loc.slug, method });
    setStage("verified");
    toast("Tożsamość potwierdzona — głos ma status zweryfikowany ✓");
  };

  // ---------- etapy ----------
  if (stage === "sent") return (
    <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
      <div style={{ display: "flex", gap: 12, alignItems: "center" }}>
        <div style={{ width: 42, height: 42, borderRadius: 99, background: "var(--accent-soft)", display: "grid", placeItems: "center", fontSize: 19 }}>✉</div>
        <div>
          <div style={{ fontWeight: 600 }}>Sprawdź skrzynkę</div>
          <div className="small muted">Wysłaliśmy link potwierdzający na <b>{email}</b>. Głos zostanie doliczony po kliknięciu (link ważny 7 dni).</div>
        </div>
      </div>
      <button className="btn ghost sm" onClick={confirmEmail} style={{ borderStyle: "dashed" }}>▸ Prototyp: symuluj kliknięcie linku w e-mailu</button>
    </div>
  );

  if (stage === "confirmed" || stage === "verified") return (
    <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
      <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
        <span className="badge green">✓ głos oddany</span>
        {stage === "verified" && <span className="badge fill">✓ zweryfikowany tożsamością</span>}
      </div>
      {stage === "confirmed" && (
        <div className="card pad" style={{ background: "var(--accent-soft)", borderColor: "transparent", display: "flex", flexDirection: "column", gap: 10 }}>
          <div style={{ fontWeight: 600, fontSize: 14.5 }}>Wzmocnij swój głos</div>
          <p className="small" style={{ color: "var(--ink-2)" }}>
            Potwierdź tożsamość przez bank (mojeID) lub mObywatela. Zweryfikowane głosy mają
            największą wagę w raportach dla gmin. <b>Nie zapisujemy Twojego numeru PESEL.</b>
          </p>
          <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
            <button className="btn accent sm" onClick={() => setIdModal("mojeid")}>mojeID — przez bank</button>
            <button className="btn ghost sm" onClick={() => setIdModal("mobywatel")}>mObywatel</button>
          </div>
        </div>
      )}
      <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
        <button className="btn ghost sm" onClick={() => { navigator.clipboard && navigator.clipboard.writeText(location.href); toast("Link skopiowany"); }}>Udostępnij ↗</button>
        <Link to="/moje" className="btn quiet sm">Moje głosy →</Link>
      </div>
      {idModal && <IdentityModal method={idModal} onClose={() => setIdModal(null)} onVerified={() => verify(idModal)} />}
    </div>
  );

  // stage === 'form'
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
      <div className="radio-cards">
        {[["buy", "Jestem zainteresowany kupnem miejsca postojowego"],
          ["rent", "Jestem zainteresowany najmem miejsca postojowego"],
          ["support", "Popieram tę lokalizację (nie potrzebuję miejsca)"]].map(([val, label]) => (
          <label key={val} className={"radio-card" + (interest === val ? " sel" : "")}>
            <input type="radio" name={"interest-" + loc.id} checked={interest === val} onChange={() => { setInterest(val); setPriceBand(""); }} />
            <span style={{ fontSize: 13.5, fontWeight: 500 }}>{label}</span>
          </label>
        ))}
      </div>
      {interest === "buy" && (
        <div className="field">
          <label>Akceptowalna cena zakupu <span className="muted" style={{ fontWeight: 400 }}>(opcjonalnie)</span></label>
          <select className="select" value={priceBand} onChange={(e) => setPriceBand(e.target.value)}>
            <option value="">— wybierz —</option>
            <option>do 60 tys. zł</option><option>60–90 tys. zł</option>
            <option>90–120 tys. zł</option><option>powyżej 120 tys. zł</option>
          </select>
        </div>
      )}
      {interest === "rent" && (
        <div className="field">
          <label>Akceptowalny czynsz miesięczny <span className="muted" style={{ fontWeight: 400 }}>(opcjonalnie)</span></label>
          <select className="select" value={priceBand} onChange={(e) => setPriceBand(e.target.value)}>
            <option value="">— wybierz —</option>
            <option>do 200 zł/mc</option><option>200–350 zł/mc</option>
            <option>350–500 zł/mc</option><option>powyżej 500 zł/mc</option>
          </select>
        </div>
      )}
      <div className="field">
        <label>Adres e-mail</label>
        <input className="input" type="email" placeholder="twoj@email.pl" value={email} onChange={(e) => setEmail(e.target.value)} />
        <span className="hint">Wyślemy link potwierdzający (double opt-in). Jeden adres = jeden głos na lokalizację.</span>
      </div>
      <label className="checkrow">
        <input type="checkbox" checked={rodo} onChange={(e) => setRodo(e.target.checked)} />
        <span>Wyrażam zgodę na przetwarzanie danych w celu badania zainteresowania lokalizacjami budowli ochronnych i przekazywania <b>zagregowanych</b> statystyk samorządom i inwestorom. <b>*</b></span>
      </label>
      <label className="checkrow">
        <input type="checkbox" checked={contact} onChange={(e) => setContact(e.target.checked)} />
        <span>Chcę otrzymywać informacje o postępach projektu w tej lokalizacji (opcjonalnie).</span>
      </label>
      <Turnstile ok={ts} onOk={() => setTs(true)} />
      {err && <div className="badge red" style={{ alignSelf: "flex-start" }}>{err}</div>}
      <button className="btn accent block lg" onClick={submit}>Oddaj głos</button>
      <Disclaimer />
    </div>
  );
}

// ---------- symulacja brokera e-ID ----------
function IdentityModal({ method, onClose, onVerified }) {
  const [step, setStep] = useState(0);
  const labels = method === "mojeid"
    ? { title: "mojeID — weryfikacja przez bank", sub: "Zostaniesz przekierowany do logowania w swojej bankowości elektronicznej.", action: "Zaloguj się do banku" }
    : { title: "mObywatel — weryfikacja zdalna", sub: "Weryfikacja przez aplikację mObywatel (broker e-ID, poziom eIDAS substantial).", action: "Otwórz mObywatel" };
  useEffect(() => {
    if (step === 1) { const t = setTimeout(() => setStep(2), 1400); return () => clearTimeout(t); }
  }, [step]);
  return (
    <Modal onClose={onClose} width={440}>
      <div style={{ padding: 24, display: "flex", flexDirection: "column", gap: 14 }}>
        <div className="kicker">symulacja przekierowania do brokera e-id</div>
        <h3 style={{ fontSize: 19 }}>{labels.title}</h3>
        {step === 0 && (<React.Fragment>
          <p className="small muted">{labels.sub}</p>
          <div className="card pad" style={{ background: "var(--surface-2)", borderColor: "transparent", fontSize: 12.5, color: "var(--ink-2)", lineHeight: 1.6 }}>
            Przekazany zostanie wyłącznie minimalny zakres danych. Numer PESEL jest przetwarzany
            <b> przelotnie w pamięci</b> i zapisywany wyłącznie jako nieodwracalny skrót (HMAC)
            gwarantujący zasadę „1 osoba = 1 głos". Imię i nazwisko nie są zapisywane.
          </div>
          <button className="btn accent block" onClick={() => setStep(1)}>{labels.action}</button>
          <button className="btn quiet sm" onClick={onClose}>Anuluj</button>
        </React.Fragment>)}
        {step === 1 && (
          <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 12, padding: "22px 0" }}>
            <div style={{ width: 30, height: 30, border: "3px solid var(--accent)", borderTopColor: "transparent", borderRadius: 99, animation: "spin 0.8s linear infinite" }}></div>
            <p className="small muted">Trwa autoryzacja u dostawcy tożsamości…</p>
          </div>
        )}
        {step === 2 && (<React.Fragment>
          <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
            <span className="badge green">✓ tożsamość potwierdzona</span>
          </div>
          <p className="small muted">Atrybuty zostały odebrane i natychmiast porzucone. Zapisano wyłącznie skrót HMAC.</p>
          <button className="btn green block" onClick={onVerified}>Wróć do lokalizacji</button>
        </React.Fragment>)}
      </div>
    </Modal>
  );
}

// ---------- formularz leadowy ----------
function LeadForm({ type, fields, sourcePage }) {
  const [vals, setVals] = useState({});
  const [ts, setTs] = useState(false);
  const [sent, setSent] = useState(false);
  const [err, setErr] = useState(null);
  const set = (k) => (e) => setVals({ ...vals, [k]: e.target.value });
  if (sent) return (
    <div className="card pad" style={{ background: "var(--green-soft)", borderColor: "transparent", display: "flex", gap: 12, alignItems: "center" }}>
      <span style={{ fontSize: 22 }}>✓</span>
      <div>
        <div style={{ fontWeight: 600 }}>Dziękuję za zgłoszenie</div>
        <div className="small muted">Odezwę się w ciągu 2 dni roboczych.</div>
      </div>
    </div>
  );
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
      {fields.map(([key, label, opts]) => (
        <div className="field" key={key}>
          <label>{label}{opts && opts.required && " *"}</label>
          {opts && opts.textarea
            ? <textarea className="textarea" value={vals[key] || ""} onChange={set(key)} placeholder={opts.placeholder || ""}></textarea>
            : <input className="input" value={vals[key] || ""} onChange={set(key)} placeholder={(opts && opts.placeholder) || ""} />}
        </div>
      ))}
      <Turnstile ok={ts} onOk={() => setTs(true)} />
      {err && <div className="badge red" style={{ alignSelf: "flex-start" }}>{err}</div>}
      <button className="btn primary block" onClick={() => {
        const req = fields.filter(([k, l, o]) => o && o.required).map(([k]) => k);
        if (req.some((k) => !(vals[k] || "").trim())) return setErr("Uzupełnij pola wymagane.");
        if (!/.+@.+\..+/.test(vals.email || "")) return setErr("Podaj prawidłowy adres e-mail.");
        if (!ts) return setErr("Potwierdź weryfikację antybotową.");
        Store.set({ leads: [...Store.get().leads, { type, ...vals, page: sourcePage, ts: Date.now(), status: "new" }] });
        Store.audit("system", "lead_created", "lead", { type, page: sourcePage });
        setSent(true);
      }}>Wyślij zgłoszenie</button>
      <p className="small" style={{ color: "var(--ink-3)", fontSize: 12 }}>Dane z formularza służą wyłącznie do kontaktu w sprawie zapytania.</p>
    </div>
  );
}

Object.assign(window, {
  navigate, Link, Nav, Footer, LogoMark, LogoWordmark, Modal, Turnstile, Disclaimer,
  VoteCounter, VoteDistribution, VoteFlow, IdentityModal, LeadForm, ToastHost, toast,
});
