/* Saints Calendar — Auth, Saved resources, Autocomplete */

const { useState: useStateA, useEffect: useEffectA, useRef: useRefA, useMemo: useMemoA } = React;

// ===== AUTH =====
const AUTH_KEY = "sc.auth.v1";
const AuthContext = React.createContext(null);

const AuthProvider = ({ children }) => {
  const [user, setUser] = useStateA(() => {
    try { return JSON.parse(localStorage.getItem(AUTH_KEY) || "null"); } catch { return null; }
  });
  useEffectA(() => {
    if (user) localStorage.setItem(AUTH_KEY, JSON.stringify(user));
    else localStorage.removeItem(AUTH_KEY);
  }, [user]);

  const signIn = ({ name, email, prefs = {} }) => {
    setUser({ name: name || email.split("@")[0], email, prefs, joinedAt: new Date().toISOString() });
  };
  const signOut = () => setUser(null);
  const updatePrefs = (prefs) => setUser(u => u ? { ...u, prefs: { ...u.prefs, ...prefs } } : u);

  return <AuthContext.Provider value={{ user, signIn, signOut, updatePrefs }}>{children}</AuthContext.Provider>;
};
const useAuth = () => React.useContext(AuthContext);

// ===== SAVED RESOURCES =====
const SAVED_KEY = "sc.saved.v1";
const SavedContext = React.createContext(null);

const SavedProvider = ({ children }) => {
  const [saved, setSaved] = useStateA(() => {
    try { return JSON.parse(localStorage.getItem(SAVED_KEY) || "[]"); } catch { return []; }
  });
  useEffectA(() => { localStorage.setItem(SAVED_KEY, JSON.stringify(saved)); }, [saved]);

  const save = (item) => {
    // item: { id, type: 'saint'|'quote'|'prayer'|'patronage'|'order'|'reading', title, subtitle?, ref?, payload? }
    setSaved(s => s.find(x => x.id === item.id) ? s : [{ ...item, savedAt: Date.now() }, ...s]);
  };
  const unsave = (id) => setSaved(s => s.filter(x => x.id !== id));
  const isSaved = (id) => saved.some(x => x.id === id);
  const toggle = (item) => isSaved(item.id) ? unsave(item.id) : save(item);

  return <SavedContext.Provider value={{ saved, save, unsave, isSaved, toggle }}>{children}</SavedContext.Provider>;
};
const useSaved = () => React.useContext(SavedContext);

// ===== SAVED VIEW =====
const SavedView = ({ onOpenSaint, onNavigate }) => {
  const { saved, unsave } = useSaved();
  const auth = useAuth();
  const [filter, setFilter] = useStateA("all");
  const types = ["all", "saint", "quote", "prayer", "patronage", "order", "reading"];
  const filtered = filter === "all" ? saved : saved.filter(s => s.type === filter);

  return (
    <div className="view-enter">
      <section style={{ padding: "48px 0 24px", borderBottom: "1px solid var(--hairline-soft)" }}>
        <div className="container">
          <div className="t-rubric mb-2">Library</div>
          <h1 className="t-display" style={{ fontSize: 56, marginBottom: 8 }}>Saved <span style={{ color: "var(--ink-mute)", fontStyle: "italic" }}>resources</span></h1>
          <p style={{ fontSize: 16, color: "var(--ink-soft)", maxWidth: 640 }}>
            Saints, quotes, prayers, and readings you have set aside. {auth.user ? `Synced to ${auth.user.email}.` : "Sign in to sync across devices."}
          </p>
          <div className="flex gap-2 mt-4" style={{ flexWrap: "wrap" }}>
            {types.map(t => (
              <button key={t} className={`chip ${filter === t ? "active" : ""}`} onClick={() => setFilter(t)}>
                {t === "all" ? `All (${saved.length})` : `${t}s (${saved.filter(s => s.type === t).length})`}
              </button>
            ))}
            {!auth.user && (
              <button className="btn btn-sm" style={{ marginLeft: "auto" }} onClick={() => onNavigate("login")}>Sign in to sync</button>
            )}
          </div>
        </div>
      </section>

      <div className="container" style={{ paddingTop: 32, paddingBottom: 80 }}>
        {filtered.length === 0 && (
          <div style={{ textAlign: "center", padding: "60px 0", color: "var(--ink-mute)" }}>
            <Fleuron />
            <p style={{ fontFamily: "var(--font-display)", fontSize: 22, fontStyle: "italic", marginTop: 16 }}>Your library is empty.</p>
            <p style={{ fontSize: 14, marginTop: 8 }}>Save a saint, quote, prayer, or reading from any page — the bookmark icon stores them here.</p>
          </div>
        )}
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(320px, 1fr))", gap: 16 }}>
          {filtered.map(item => (
            <div key={item.id} className="card saved-card" style={{ padding: 20, position: "relative" }}>
              <div className="t-rubric" style={{ color: "var(--gilt-deep)", marginBottom: 6 }}>{item.type}</div>
              <div style={{ fontFamily: "var(--font-display)", fontSize: 20, lineHeight: 1.2, marginBottom: 4 }}>{item.title}</div>
              {item.subtitle && <div className="t-meta" style={{ fontStyle: "italic" }}>{item.subtitle}</div>}
              {item.payload && (
                <p style={{ fontSize: 13, color: "var(--ink-soft)", marginTop: 10, lineHeight: 1.55 }}>
                  {item.payload.length > 180 ? item.payload.slice(0, 180) + "…" : item.payload}
                </p>
              )}
              <div className="flex gap-2 mt-3">
                {item.ref && (
                  <button className="btn btn-sm" onClick={() => onOpenSaint(item.ref)}>Open</button>
                )}
                <button className="btn btn-ghost btn-sm" onClick={() => unsave(item.id)} style={{ marginLeft: "auto", color: "var(--rubric)" }}>Remove</button>
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
};

// ===== SAVE BUTTON (generic) =====
const SaveButton = ({ item, size = "sm", label }) => {
  const { isSaved, toggle } = useSaved();
  const saved = isSaved(item.id);
  return (
    <button onClick={(e) => { e.stopPropagation(); toggle(item); }}
      className={`btn ${saved ? "btn-gilt" : ""} ${size === "sm" ? "btn-sm" : ""}`}>
      <IconBookmark filled={saved} size={12} /> {saved ? "Saved" : (label || "Save")}
    </button>
  );
};

// ===== AUTOCOMPLETE =====
const Autocomplete = ({ value, onChange, onSubmit, onSelectSaint, placeholder, autoFocus, large }) => {
  const [open, setOpen] = useStateA(false);
  const [active, setActive] = useStateA(0);
  const inputRef = useRefA(null);

  const suggestions = useMemoA(() => {
    if (!value || value.trim().length < 1) return [];
    const v = value.toLowerCase().trim();
    const out = [];
    // Saints
    window.SAINTS.forEach(s => {
      const hay = `${s.honorific} ${s.name} ${s.epithet}`.toLowerCase();
      if (hay.includes(v)) out.push({ kind: "saint", id: s.id, label: `${s.honorific} ${s.name}`, sub: `${s.epithet} · ${formatDate(s.feast.month, s.feast.day)}`, saint: s });
    });
    // Patronages
    const pats = new Set();
    window.SAINTS.forEach(s => s.patronage.forEach(p => { if (p.toLowerCase().includes(v)) pats.add(p); }));
    [...pats].slice(0, 4).forEach(p => out.push({ kind: "patronage", id: `pat-${p}`, label: p, sub: "Patronage", query: p }));
    // Orders
    const orders = new Set();
    window.SAINTS.forEach(s => { if (s.order && s.order.toLowerCase().includes(v)) orders.add(s.order); });
    [...orders].slice(0, 3).forEach(o => out.push({ kind: "order", id: `ord-${o}`, label: o, sub: "Religious order", query: o }));
    // Regions
    const regs = new Set();
    window.SAINTS.forEach(s => { if (s.region.toLowerCase().includes(v)) regs.add(s.region); });
    [...regs].slice(0, 3).forEach(r => out.push({ kind: "region", id: `reg-${r}`, label: r, sub: "Region", query: r }));
    return out.slice(0, 10);
  }, [value]);

  useEffectA(() => { setActive(0); }, [value]);

  const choose = (item) => {
    setOpen(false);
    if (item.kind === "saint" && onSelectSaint) onSelectSaint(item.id);
    else if (onSubmit) onSubmit(item.query || item.label);
  };

  const onKey = (e) => {
    if (!open || suggestions.length === 0) {
      if (e.key === "Enter" && onSubmit) { e.preventDefault(); onSubmit(value); }
      return;
    }
    if (e.key === "ArrowDown") { e.preventDefault(); setActive(a => (a + 1) % suggestions.length); }
    else if (e.key === "ArrowUp") { e.preventDefault(); setActive(a => (a - 1 + suggestions.length) % suggestions.length); }
    else if (e.key === "Enter") { e.preventDefault(); choose(suggestions[active]); }
    else if (e.key === "Escape") { setOpen(false); inputRef.current?.blur(); }
  };

  return (
    <div className="ac-wrap">
      <div className={`search-shell ${large ? "search-large" : ""}`}>
        <IconSearch size={large ? 18 : 14} />
        <input
          ref={inputRef}
          type="text"
          value={value}
          onChange={(e) => { onChange(e.target.value); setOpen(true); }}
          onFocus={() => setOpen(true)}
          onBlur={() => setTimeout(() => setOpen(false), 160)}
          onKeyDown={onKey}
          placeholder={placeholder}
          autoFocus={autoFocus}
          style={{ marginLeft: 14 }}
        />
        <span className="search-key">/</span>
      </div>
      {open && suggestions.length > 0 && (
        <div className="ac-pop">
          {suggestions.map((s, i) => (
            <button key={s.id}
              onMouseDown={(e) => { e.preventDefault(); choose(s); }}
              onMouseEnter={() => setActive(i)}
              className={`ac-item ${active === i ? "active" : ""}`}>
              <span className="ac-kind">{s.kind === "saint" ? "✦" : s.kind === "patronage" ? "❦" : s.kind === "order" ? "✠" : "◈"}</span>
              <span className="ac-text">
                <span className="ac-label">{s.label}</span>
                <span className="ac-sub">{s.sub}</span>
              </span>
              <span className="ac-meta">{s.kind}</span>
            </button>
          ))}
        </div>
      )}
    </div>
  );
};

// ===== LOGIN VIEW — Magic link + Passkey (no passwords) =====
const LoginView = ({ onNavigate }) => {
  const auth = useAuth();
  const [step, setStep] = useStateA("choose"); // choose | email-sent | passkey-pending | new-account
  const [email, setEmail] = useStateA("");
  const [name, setName] = useStateA("");
  const [prefs, setPrefs] = useStateA({ daily: true, weekly: false, novenas: true, devotional: true });
  const [error, setError] = useStateA("");
  const [busy, setBusy] = useStateA(false);

  const passkeySupported = typeof window !== "undefined"
    && !!window.PublicKeyCredential
    && typeof PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable === "function";

  // Demo: simulate the network round-trip; on production, POST to /api/auth/magic-link
  const sendMagicLink = async (e) => {
    e.preventDefault();
    if (!email || !email.includes("@")) { setError("Please enter a valid email."); return; }
    setError(""); setBusy(true);
    try {
      // await fetch("/api/auth/magic-link", { method: "POST", body: JSON.stringify({ email }) });
      await new Promise(r => setTimeout(r, 700));
      setStep("email-sent");
    } catch (err) { setError("Could not send link. Try again."); }
    finally { setBusy(false); }
  };

  // Demo: passkey ceremony — production wires navigator.credentials.get against a server challenge
  const signInWithPasskey = async () => {
    if (!passkeySupported) { setError("Passkeys are not supported on this device."); return; }
    setError(""); setBusy(true); setStep("passkey-pending");
    try {
      // const opts = await fetch("/api/auth/passkey/challenge").then(r => r.json());
      // const cred = await navigator.credentials.get({ publicKey: opts });
      // const res = await fetch("/api/auth/passkey/verify", { method: "POST", body: JSON.stringify(cred) });
      await new Promise(r => setTimeout(r, 1100));
      auth.signIn({ name: "Returning member", email: "you@example.com", method: "passkey", prefs: { daily: true, weekly: false, novenas: true, devotional: true } });
      onNavigate("saved");
    } catch (err) {
      setError("Passkey sign-in cancelled.");
      setStep("choose");
    } finally { setBusy(false); }
  };

  // Demo: register a new passkey for a new account — wires to navigator.credentials.create
  const createWithPasskey = async (e) => {
    e.preventDefault();
    if (!email || !email.includes("@")) { setError("Please enter a valid email."); return; }
    if (!name) { setError("Please enter your name."); return; }
    if (!passkeySupported) { setError("Passkeys are not supported here. Use the magic link instead."); return; }
    setError(""); setBusy(true);
    try {
      // const opts = await fetch("/api/auth/passkey/register/options", { method: "POST", body: JSON.stringify({ email, name }) }).then(r => r.json());
      // const cred = await navigator.credentials.create({ publicKey: opts });
      // await fetch("/api/auth/passkey/register/verify", { method: "POST", body: JSON.stringify(cred) });
      await new Promise(r => setTimeout(r, 1100));
      auth.signIn({ name, email, method: "passkey", prefs });
      onNavigate("saved");
    } catch (err) {
      setError("Could not create passkey. You can still use the magic link.");
    } finally { setBusy(false); }
  };

  // ----- Signed in: account view -----
  if (auth.user) {
    return (
      <div className="view-enter">
        <section style={{ padding: "60px 0", maxWidth: 540, margin: "0 auto" }}>
          <div className="container">
            <div className="t-rubric text-center mb-3">Account</div>
            <h1 className="t-display text-center" style={{ fontSize: 48, marginBottom: 10 }}>Pax tecum, {auth.user.name}</h1>
            <Fleuron />
            <div className="card" style={{ padding: 28, marginTop: 24 }}>
              <div className="t-rubric mb-1">Email</div>
              <div style={{ fontFamily: "var(--font-display)", fontSize: 19, marginBottom: 6 }}>{auth.user.email}</div>
              <div className="t-meta" style={{ marginBottom: 18 }}>
                Signed in via {auth.user.method === "passkey" ? "passkey" : "magic link"}
              </div>
              <div className="t-rubric mb-2">Daily updates</div>
              {[["daily", "Today's feast — every morning"], ["weekly", "Weekly digest — Sunday evening"], ["novenas", "Novena reminders from Nov3na"], ["devotional", "Devotional reflections"]].map(([k, l]) => (
                <label key={k} style={{ display: "flex", gap: 10, padding: "8px 0", alignItems: "center" }}>
                  <input type="checkbox" checked={!!(auth.user.prefs && auth.user.prefs[k])} onChange={(e) => auth.updatePrefs({ [k]: e.target.checked })} />
                  <span>{l}</span>
                </label>
              ))}
              <div className="flex gap-2 mt-4">
                <button className="btn btn-sm" onClick={() => onNavigate("saved")}>My library</button>
                {passkeySupported && auth.user.method !== "passkey" && (
                  <button className="btn btn-sm" onClick={async () => {
                    // navigator.credentials.create flow on production
                    await new Promise(r => setTimeout(r, 700));
                    auth.updatePrefs({}); // no-op; just to flash UI
                    alert("Passkey added (demo). On production this calls navigator.credentials.create.");
                  }}>Add a passkey</button>
                )}
                <button className="btn btn-sm" onClick={auth.signOut} style={{ marginLeft: "auto", color: "var(--rubric)" }}>Sign out</button>
              </div>
            </div>
          </div>
        </section>
      </div>
    );
  }

  // ----- Magic link sent confirmation -----
  if (step === "email-sent") {
    return (
      <div className="view-enter">
        <section style={{ padding: "80px 0", maxWidth: 520, margin: "0 auto" }}>
          <div className="container text-center">
            <div className="auth-glyph">✉</div>
            <div className="t-rubric mb-3">Check your inbox</div>
            <h1 className="t-display" style={{ fontSize: 42, marginBottom: 12 }}>A link is on its way</h1>
            <Fleuron />
            <p style={{ color: "var(--ink-soft)", marginTop: 18, maxWidth: 400, marginInline: "auto", fontSize: 15 }}>
              We sent a sign-in link to <strong style={{ color: "var(--ink)" }}>{email}</strong>. Open it on this device to continue. The link expires in 15 minutes.
            </p>
            <div className="flex gap-2" style={{ justifyContent: "center", marginTop: 28 }}>
              <button className="btn btn-sm" onClick={() => { setStep("choose"); setEmail(""); }}>Use a different email</button>
              <button className="btn btn-sm btn-ghost" onClick={sendMagicLink}>Resend link</button>
            </div>
            {/* Demo affordance — remove on production */}
            <button onClick={() => { auth.signIn({ name: email.split("@")[0], email, method: "magic-link", prefs }); onNavigate("saved"); }}
              className="t-meta auth-demo-link">
              [demo] simulate clicking the link
            </button>
          </div>
        </section>
      </div>
    );
  }

  // ----- Passkey pending -----
  if (step === "passkey-pending") {
    return (
      <div className="view-enter">
        <section style={{ padding: "100px 0", maxWidth: 460, margin: "0 auto" }}>
          <div className="container text-center">
            <div className="auth-glyph auth-glyph-spin">⌖</div>
            <div className="t-rubric mb-3">Awaiting your device</div>
            <h1 className="t-display" style={{ fontSize: 36, marginBottom: 12 }}>Use your passkey</h1>
            <p style={{ color: "var(--ink-soft)", marginTop: 12, fontSize: 14 }}>
              Touch your security key, fingerprint sensor, or Face ID to continue.
            </p>
          </div>
        </section>
      </div>
    );
  }

  // ----- New account flow -----
  if (step === "new-account") {
    return (
      <div className="view-enter">
        <section style={{ padding: "60px 0", maxWidth: 520, margin: "0 auto" }}>
          <div className="container">
            <div className="t-rubric text-center mb-3">Create an account</div>
            <h1 className="t-display text-center" style={{ fontSize: 44, marginBottom: 4 }}>Begin</h1>
            <Fleuron />
            <form onSubmit={createWithPasskey} className="card" style={{ padding: 28, marginTop: 24 }}>
              <label className="login-field">
                <span>Name</span>
                <input value={name} onChange={(e) => setName(e.target.value)} required placeholder="Mary Magdalene" />
              </label>
              <label className="login-field">
                <span>Email</span>
                <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} required placeholder="you@example.com" />
              </label>
              <div style={{ marginTop: 18 }}>
                <div className="t-rubric mb-2">Send me</div>
                {[["daily", "Today's feast (daily)"], ["weekly", "Weekly digest"], ["novenas", "Novena reminders from Nov3na"], ["devotional", "Devotional reflections"]].map(([k, l]) => (
                  <label key={k} style={{ display: "flex", gap: 10, padding: "5px 0", fontSize: 14 }}>
                    <input type="checkbox" checked={prefs[k]} onChange={(e) => setPrefs(p => ({ ...p, [k]: e.target.checked }))} />
                    <span>{l}</span>
                  </label>
                ))}
              </div>
              {error && <div className="auth-error">{error}</div>}
              <button type="submit" className="btn btn-primary" style={{ width: "100%", justifyContent: "center", marginTop: 18, padding: "14px" }} disabled={busy || !passkeySupported}>
                {busy ? "Creating…" : "Create with passkey"}
              </button>
              <button type="button" onClick={async (e) => {
                e.preventDefault();
                if (!email) { setError("Email is required."); return; }
                if (!name) { setError("Name is required."); return; }
                setError(""); setBusy(true);
                try { await new Promise(r => setTimeout(r, 700)); setStep("email-sent"); }
                finally { setBusy(false); }
              }} className="btn" style={{ width: "100%", justifyContent: "center", marginTop: 10 }} disabled={busy}>
                Or send a magic link instead
              </button>
              <div style={{ textAlign: "center", marginTop: 16 }}>
                <button type="button" onClick={() => { setStep("choose"); setError(""); }}
                  style={{ fontSize: 13, color: "var(--gilt-deep)", borderBottom: "1px solid var(--gilt)" }}>
                  ← Back
                </button>
              </div>
            </form>
          </div>
        </section>
      </div>
    );
  }

  // ----- Default: choose method -----
  return (
    <div className="view-enter">
      <section style={{ padding: "60px 0", maxWidth: 520, margin: "0 auto" }}>
        <div className="container">
          <div className="t-rubric text-center mb-3">Welcome back</div>
          <h1 className="t-display text-center" style={{ fontSize: 52, marginBottom: 4 }}>Sign in</h1>
          <Fleuron />
          <p style={{ textAlign: "center", color: "var(--ink-soft)", fontSize: 15, marginTop: 16, maxWidth: 400, marginInline: "auto" }}>
            We don't use passwords. Choose a passkey on your device, or have a one-time link sent to your email.
          </p>

          {passkeySupported && (
            <button onClick={signInWithPasskey} className="auth-method-btn" disabled={busy}>
              <span className="auth-method-icon">⌖</span>
              <span className="auth-method-text">
                <span className="auth-method-title">Sign in with a passkey</span>
                <span className="auth-method-sub">Use Face ID, Touch ID, Windows Hello, or a security key.</span>
              </span>
              <span className="auth-method-chev">→</span>
            </button>
          )}

          <form onSubmit={sendMagicLink} className="card" style={{ padding: 24, marginTop: 14 }}>
            <label className="login-field">
              <span>Email a sign-in link</span>
              <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} required placeholder="you@example.com" />
            </label>
            {error && <div className="auth-error">{error}</div>}
            <button type="submit" className="btn btn-primary" style={{ width: "100%", justifyContent: "center", marginTop: 14, padding: "12px" }} disabled={busy}>
              {busy ? "Sending…" : "Email me a link"}
            </button>
          </form>

          <div style={{ textAlign: "center", marginTop: 22 }}>
            <button type="button" onClick={() => { setStep("new-account"); setError(""); }}
              style={{ fontSize: 13, color: "var(--gilt-deep)", borderBottom: "1px solid var(--gilt)" }}>
              New here? Create an account
            </button>
          </div>

          <p className="t-meta" style={{ textAlign: "center", marginTop: 18, fontSize: 11, color: "var(--ink-mute)" }}>
            Authenticated with magic link or WebAuthn passkey · No passwords stored.
          </p>
        </div>
      </section>
    </div>
  );
};

Object.assign(window, {
  AuthProvider, useAuth, SavedProvider, useSaved,
  SavedView, LoginView, Autocomplete, SaveButton,
});
