// LoginView, SettingsView, SlotsView, LogsView, ReservationsView
// Wszystkie fetchują dane przez window.ZlapApi

const { useState: uS, useEffect: uE, useMemo: uM, useCallback: uC } = React;
const A2 = window.ZlapApi.adapters;

/* ============================ LOGIN ============================ */
function LoginView({ onLogin }) {
  const [email, setEmail] = uS("");
  const [password, setPassword] = uS("");
  const [busy, setBusy] = uS(false);
  const [err, setErr] = uS("");

  const submit = async (e) => {
    e.preventDefault();
    setBusy(true); setErr("");
    try {
      await onLogin(email, password);
    } catch (ex) {
      setErr(ex.message || "Błąd logowania");
    } finally {
      setBusy(false);
    }
  };

  return (
    <div className="app-bg" style={{
      minHeight: "100vh", display: "flex", alignItems: "center", justifyContent: "center", padding: 20,
    }}>
      <form onSubmit={submit} className="card" style={{ padding: 28, width: "100%", maxWidth: 400 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 22 }}>
          <span style={{
            width: 28, height: 28, borderRadius: 4,
            background: "var(--hit)", color: "var(--bg)",
            display: "inline-flex", alignItems: "center", justifyContent: "center",
          }}>
            <Icon name="zap" size={16} stroke={2.4}/>
          </span>
          <div>
            <div style={{ fontSize: 18, fontWeight: 600, letterSpacing: "-0.01em" }}>zlap-termin</div>
            <div className="mono" style={{ fontSize: 11, color: "var(--fg-muted)" }}>panel administracyjny</div>
          </div>
        </div>
        <label style={{ display: "block", marginBottom: 10 }}>
          <div style={{ fontSize: 12, color: "var(--fg-muted)", marginBottom: 4 }}>Email</div>
          <input className="input" type="email" required autoFocus value={email} onChange={e=>setEmail(e.target.value)} />
        </label>
        <label style={{ display: "block", marginBottom: 14 }}>
          <div style={{ fontSize: 12, color: "var(--fg-muted)", marginBottom: 4 }}>Hasło</div>
          <input className="input" type="password" required value={password} onChange={e=>setPassword(e.target.value)} />
        </label>
        {err && (
          <div style={{ color: "var(--err)", fontSize: 12, marginBottom: 10 }}>
            <Icon name="alert" size={12} /> {err}
          </div>
        )}
        <button type="submit" className="btn primary" disabled={busy} style={{ width: "100%", justifyContent: "center" }}>
          {busy ? "Logowanie…" : "Zaloguj"}
        </button>
      </form>
    </div>
  );
}
window.LoginView = LoginView;

/* ============================ SETTINGS ============================ */
function Section({ title, children, right }) {
  return (
    <div className="card" style={{ padding: 16, marginBottom: 14 }}>
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 12 }}>
        <div style={{ fontSize: 14, fontWeight: 600 }}>{title}</div>
        {right}
      </div>
      {children}
    </div>
  );
}

function Field({ label, hint, children }) {
  return (
    <label style={{ display: "block", marginBottom: 10 }}>
      <div style={{ fontSize: 12, color: "var(--fg-muted)", marginBottom: 4 }}>{label}</div>
      {children}
      {hint && <div style={{ fontSize: 11, color: "var(--fg-dim)", marginTop: 3 }}>{hint}</div>}
    </label>
  );
}

function SettingsView({ toast }) {
  const [data, setData] = uS(null);
  const [saving, setSaving] = uS(false);
  const [testing, setTesting] = uS("");

  uE(() => {
    window.ZlapApi.getSettings()
      .then(s => setData(A2.settings(s)))
      .catch(e => toast(`Błąd wczytywania ustawień: ${e.message}`, "err"));
  }, []);

  if (!data) return <div style={{ padding: 18 }}><div className="mono" style={{color:"var(--fg-muted)"}}>Ładowanie…</div></div>;

  const set = (k, v) => setData(d => ({ ...d, [k]: v }));

  const save = async () => {
    setSaving(true);
    try {
      const fresh = await window.ZlapApi.saveSettings(A2.settingsToApi(data));
      setData(A2.settings(fresh));
      toast("Zapisano ustawienia", "ok");
    } catch (e) {
      toast(`Błąd zapisu: ${e.message}`, "err");
    } finally {
      setSaving(false);
    }
  };

  const runTest = async (kind) => {
    setTesting(kind);
    try {
      const fn = { infocar: "testInfocar", email: "testEmail", telegram: "testTelegram" }[kind];
      const r = await window.ZlapApi[fn]();
      toast(`Test ${kind}: ${r.ok ? "OK" : "BŁĄD"} — ${r.message}`, r.ok ? "ok" : "err");
    } catch (e) {
      toast(`Test ${kind}: ${e.message}`, "err");
    } finally {
      setTesting("");
    }
  };

  return (
    <div style={{ padding: "18px 22px 80px", maxWidth: 880 }}>
      <div style={{ fontSize: 18, fontWeight: 600, letterSpacing: "-0.01em", marginBottom: 4 }}>Ustawienia</div>
      <div style={{ color: "var(--fg-muted)", fontSize: 12, marginBottom: 16 }}>
        Sekrety są maskowane <span className="mono">••••••••</span>. Zostaw puste żeby nie nadpisywać.
      </div>

      <Section title="Dane kandydata (wpisywane w formularzu info-car)">
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>
          <Field label="Imię"><input className="input" value={data.candidateFirstName} onChange={e=>set("candidateFirstName", e.target.value)} /></Field>
          <Field label="Nazwisko"><input className="input" value={data.candidateLastName} onChange={e=>set("candidateLastName", e.target.value)} /></Field>
          <Field label="PESEL"><input className="input mono" maxLength={11} value={data.candidatePesel} onChange={e=>set("candidatePesel", e.target.value)} /></Field>
          <Field label="Numer PKK"><input className="input mono" value={data.candidatePkk} onChange={e=>set("candidatePkk", e.target.value)} /></Field>
          <Field label="Email"><input className="input" type="email" value={data.candidateEmail} onChange={e=>set("candidateEmail", e.target.value)} /></Field>
          <Field label="Telefon" hint="format +48..."><input className="input mono" value={data.candidatePhone} onChange={e=>set("candidatePhone", e.target.value)} /></Field>
        </div>
      </Section>

      <Section
        title="Konto info-car.pl (botowe)"
        right={<button className="btn" disabled={testing==="infocar"} onClick={()=>runTest("infocar")}>
          {testing==="infocar" ? "Testuję…" : "Test"}
        </button>}
      >
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>
          <Field label="Email konta info-car"><input className="input" value={data.infocarEmail} onChange={e=>set("infocarEmail", e.target.value)} /></Field>
          <Field label="Hasło" hint="puste = nie zmieniaj"><input className="input" type="password" value={data.infocarPassword} onChange={e=>set("infocarPassword", e.target.value)} /></Field>
        </div>
      </Section>

      <Section
        title="Email (powiadomienia z linkiem do płatności)"
        right={<button className="btn" disabled={testing==="email"} onClick={()=>runTest("email")}>
          {testing==="email" ? "Testuję…" : "Test"}
        </button>}
      >
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>
          <Field label="SMTP host"><input className="input" value={data.smtpHost} onChange={e=>set("smtpHost", e.target.value)} /></Field>
          <Field label="SMTP port"><input className="input mono" type="number" value={data.smtpPort} onChange={e=>set("smtpPort", e.target.value)} /></Field>
          <Field label="SMTP user"><input className="input" value={data.smtpUser} onChange={e=>set("smtpUser", e.target.value)} /></Field>
          <Field label="SMTP hasło" hint="puste = nie zmieniaj"><input className="input" type="password" value={data.smtpPassword} onChange={e=>set("smtpPassword", e.target.value)} /></Field>
          <Field label="Adres nadawcy (From)"><input className="input" value={data.smtpFrom} onChange={e=>set("smtpFrom", e.target.value)} /></Field>
          <Field label="Odbiorcy (CSV)" hint="kilka adresów po przecinku — wszystkie dostaną link"><input className="input" value={data.smtpTo} onChange={e=>set("smtpTo", e.target.value)} /></Field>
        </div>
      </Section>

      <Section
        title="Telegram (opcjonalne)"
        right={<button className="btn" disabled={testing==="telegram"} onClick={()=>runTest("telegram")}>
          {testing==="telegram" ? "Testuję…" : "Test"}
        </button>}
      >
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>
          <Field label="Bot token" hint="puste = nie zmieniaj"><input className="input" type="password" value={data.tgBotToken} onChange={e=>set("tgBotToken", e.target.value)} /></Field>
          <Field label="Chat ID"><input className="input mono" value={data.tgChatId} onChange={e=>set("tgChatId", e.target.value)} /></Field>
        </div>
      </Section>

      <div style={{ display: "flex", gap: 8, justifyContent: "flex-end" }}>
        <button className="btn primary" disabled={saving} onClick={save}>
          {saving ? "Zapisywanie…" : "Zapisz"}
        </button>
      </div>
    </div>
  );
}
window.SettingsView = SettingsView;

/* ============================ SLOTS ============================ */
function SlotsView() {
  const [slots, setSlots] = uS([]);
  const [loading, setLoading] = uS(true);

  uE(() => {
    window.ZlapApi.getSlots({ limit: 200 })
      .then(rows => setSlots(rows.map(A2.slot)))
      .catch(() => {})
      .finally(() => setLoading(false));
  }, []);

  const [q, setQ] = uS("");
  const [wordF, setWordF] = uS("all");
  const [catF, setCatF] = uS("all");

  const filtered = uM(() => {
    let arr = slots.slice();
    if (wordF !== "all") arr = arr.filter(s => s.word === wordF);
    if (catF !== "all") arr = arr.filter(s => s.cat === catF);
    if (q) {
      const qq = q.toLowerCase();
      arr = arr.filter(s => (`${s.slotDate} ${s.slotTime} ${s.word} ${s.cat}`).toLowerCase().includes(qq));
    }
    return arr;
  }, [slots, q, wordF, catF]);

  const uniqWords = ["all", ...Array.from(new Set(slots.map(s => s.word)))];
  const uniqCats  = ["all", ...Array.from(new Set(slots.map(s => s.cat)))];

  return (
    <div style={{ padding: "18px 22px 80px" }}>
      <div style={{ fontSize: 18, fontWeight: 600, marginBottom: 14 }}>Terminy (historia znalezień)</div>
      <div className="card" style={{ padding: 10, marginBottom: 12, display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap" }}>
        <input className="input mono" style={{ flex: "1 1 220px", minWidth: 180 }} placeholder="Szukaj…" value={q} onChange={e=>setQ(e.target.value)} />
        <select className="select" style={{ width: "auto" }} value={wordF} onChange={e=>setWordF(e.target.value)}>
          {uniqWords.map(w => <option key={w} value={w}>{w === "all" ? "Wszystkie WORD-y" : w}</option>)}
        </select>
        <select className="select" style={{ width: "auto" }} value={catF} onChange={e=>setCatF(e.target.value)}>
          {uniqCats.map(c => <option key={c} value={c}>{c === "all" ? "Wszystkie kat." : `kat. ${c}`}</option>)}
        </select>
        <span style={{ marginLeft: "auto", color: "var(--fg-muted)", fontSize: 12 }}>
          <span className="mono">{filtered.length}</span> / {slots.length}
        </span>
      </div>
      <div className="card" style={{ padding: 0, overflow: "hidden" }}>
        <table className="table">
          <thead>
            <tr>
              <th>Znaleziony</th><th>Data</th><th>Godzina</th><th>WORD</th><th>Kat.</th><th>Typ</th>
            </tr>
          </thead>
          <tbody>
            {loading && <tr><td colSpan={6} style={{ padding: 14, color: "var(--fg-muted)" }}>Ładowanie…</td></tr>}
            {!loading && filtered.length === 0 && <tr><td colSpan={6} style={{ padding: 14, color: "var(--fg-muted)" }}>Brak wyników</td></tr>}
            {filtered.map(s => (
              <tr key={s.id}>
                <td className="mono"><RelTime date={s.foundAt} /></td>
                <td className="mono">{s.slotDate}</td>
                <td className="mono">{s.slotTime}</td>
                <td>{s.word}</td>
                <td className="mono">{s.cat}</td>
                <td className="mono">{s.examType}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}
window.SlotsView = SlotsView;

/* ============================ LOGS ============================ */
function LogsView() {
  const [events, setEvents] = uS([]);
  const [levels, setLevels] = uS(new Set(["INFO", "WARN", "ERROR"]));

  uE(() => {
    let cancelled = false;
    let sinceIso = null;
    const load = async () => {
      try {
        const rows = await window.ZlapApi.getEvents({ limit: 500 });
        if (!cancelled) {
          setEvents(rows.map(A2.event));
          if (rows.length) sinceIso = rows[0].at;
        }
      } catch (e) {}
    };
    load();
    const iv = setInterval(async () => {
      if (!sinceIso) return load();
      try {
        const rows = await window.ZlapApi.getEvents({ since: sinceIso, limit: 200 });
        if (!cancelled && rows.length) {
          const adapted = rows.map(A2.event);
          sinceIso = rows[0].at;
          setEvents(prev => [...adapted, ...prev].slice(0, 1000));
        }
      } catch (e) {}
    }, 3000);
    return () => { cancelled = true; clearInterval(iv); };
  }, []);

  const toggle = (lvl) => {
    setLevels(s => {
      const ns = new Set(s);
      if (ns.has(lvl)) ns.delete(lvl); else ns.add(lvl);
      return ns;
    });
  };

  const filtered = events.filter(e => levels.has(e.level));

  return (
    <div style={{ padding: "18px 22px 80px" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 14 }}>
        <div style={{ fontSize: 18, fontWeight: 600 }}>Logi</div>
        <div style={{ marginLeft: "auto", display: "flex", gap: 6 }}>
          {["INFO", "WARN", "ERROR"].map(l => (
            <button key={l} className={cls("btn", levels.has(l) ? "primary" : "ghost")} onClick={()=>toggle(l)}>
              {l}
            </button>
          ))}
        </div>
      </div>
      <div className="card" style={{ padding: 0, maxHeight: "70vh", overflow: "auto" }}>
        <table className="table">
          <thead><tr><th style={{width: 90}}>Poziom</th><th style={{width: 140}}>Czas</th><th>Wiadomość</th></tr></thead>
          <tbody>
            {filtered.length === 0 && <tr><td colSpan={3} style={{padding: 14, color: "var(--fg-muted)"}}>Brak zdarzeń</td></tr>}
            {filtered.map(e => (
              <tr key={e.id}>
                <td><LevelBadge level={e.level} /></td>
                <td className="mono"><RelTime date={e.at} /></td>
                <td>{e.msg}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}
window.LogsView = LogsView;

/* ============================ RESERVATIONS ============================ */
function ReservationsView({ toast }) {
  const [items, setItems] = uS([]);
  const [loading, setLoading] = uS(true);

  uE(() => {
    const load = () => window.ZlapApi.listReservations(100).then(setItems).catch(()=>{}).finally(()=>setLoading(false));
    load();
    const iv = setInterval(load, 5000);
    return () => clearInterval(iv);
  }, []);

  const copy = async (url) => {
    try { await navigator.clipboard.writeText(url); toast("Link skopiowany", "ok"); } catch (_) {}
  };

  return (
    <div style={{ padding: "18px 22px 80px" }}>
      <div style={{ fontSize: 18, fontWeight: 600, marginBottom: 14 }}>Rezerwacje</div>
      <div className="card" style={{ padding: 0, overflow: "auto" }}>
        <table className="table">
          <thead>
            <tr>
              <th>Stan</th><th>Tryb</th><th>Data/Godz</th><th>WORD</th><th>Kat.</th><th>Typ</th><th>Płatność</th><th>Kiedy</th>
            </tr>
          </thead>
          <tbody>
            {loading && <tr><td colSpan={8} style={{padding: 14, color: "var(--fg-muted)"}}>Ładowanie…</td></tr>}
            {!loading && items.length === 0 && <tr><td colSpan={8} style={{padding: 14, color: "var(--fg-muted)"}}>Brak rezerwacji</td></tr>}
            {items.map(r => (
              <tr key={r.id}>
                <td>
                  <span className={cls("badge", {
                    reserved: "ok", pending: "info", failed: "err", expired: "muted"
                  }[r.status] || "muted")}>{r.status}</span>
                </td>
                <td className="mono">{r.trigger}</td>
                <td className="mono">{r.slot_date} {r.slot_time}</td>
                <td>{r.word_name}</td>
                <td className="mono">{r.category}</td>
                <td className="mono">{r.exam_type}</td>
                <td>
                  {r.payment_url
                    ? <div style={{display:"flex", gap: 6}}>
                        <a className="btn primary" href={r.payment_url} target="_blank" rel="noopener noreferrer">
                          <Icon name="external" size={12}/> Otwórz
                        </a>
                        <button className="btn ghost" onClick={()=>copy(r.payment_url)} title="Kopiuj"><Icon name="copy" size={12}/></button>
                      </div>
                    : <span style={{color:"var(--fg-muted)"}}>—</span>
                  }
                </td>
                <td className="mono"><RelTime date={new Date(r.started_at)}/></td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}
window.ReservationsView = ReservationsView;
