/* ============================================================
   COMMONS — shared components
   ============================================================ */
const { useState, useEffect, useRef } = React;

const AVA_COLORS = ["#E8482A", "#5E7355", "#2C4A6E", "#B98326", "#6B3F5E", "#37606B", "#A8412B"];
function avaColor(seed) {
  let h = 0; for (let i = 0; i < seed.length; i++) h = (h * 31 + seed.charCodeAt(i)) >>> 0;
  return AVA_COLORS[h % AVA_COLORS.length];
}

function Avatar({ seed, label, size = 34, ring = true }) {
  const initials = (label || seed || "?").split(/[\s_]+/).slice(0, 2).map(w => w[0]).join("").toUpperCase().slice(0, 2);
  return (
    <span className="ava" style={{
      width: size, height: size, background: avaColor(seed || label || "x"),
      fontSize: size * 0.4, boxShadow: ring ? "inset 0 0 0 2px rgba(255,255,255,.2)" : "none",
    }}>{initials}</span>
  );
}

// Procedural gradient cover with soft grain + optional category label
function Cover({ seed, label, aspect = "16 / 10", radius, children, className = "", style = {} }) {
  const c = coverFor(seed);
  const img = (typeof window !== "undefined" && window.__DATA__ && window.__DATA__.images && window.__DATA__.images[seed]) || null;
  return (
    <div className={"cover " + className} style={{
      position: "relative", aspectRatio: aspect, background: c.css,
      borderRadius: radius != null ? radius : "var(--radius)", overflow: "hidden",
      ...style,
    }}>
      {img && <img src={img} alt="" loading="lazy" className="cover-img" onError={(e) => { e.target.style.display = "none"; }} />}
      <div style={{
        position: "absolute", inset: 0,
        background: `linear-gradient(${c.angle}deg, rgba(0,0,0,.18), transparent 55%)`,
      }} />
      <div style={{
        position: "absolute", inset: 0, mixBlendMode: "soft-light", opacity: .5,
        backgroundImage: "url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E\")",
      }} />
      {children}
    </div>
  );
}

function Logo({ onClick }) {
  return (
    <button className="logo" onClick={onClick} aria-label="iPanjab home">
      <img className="logo-mark" src="/favicon.svg" width="28" height="28" alt="" style={{ borderRadius: 8, display: "block" }} />
      <span className="logo-word serif"><span style={{ color: "var(--accent)" }}>i</span>Panj-<span style={{ color: "var(--teal, #37606B)" }}>āb</span></span>
    </button>
  );
}

function AuthModal({ onClose }) {
  const [mode, setMode] = useState("login");
  const [name, setName] = useState("");
  const [email, setEmail] = useState("");
  const [pw, setPw] = useState("");
  const [showPw, setShowPw] = useState(false);
  const [err, setErr] = useState("");
  const [busy, setBusy] = useState(false);
  const isReg = mode === "register";
  const submit = async (e) => {
    e.preventDefault(); setErr(""); setBusy(true);
    try {
      const url = isReg ? "/api/register" : "/api/login";
      const r = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name, email, password: pw }) });
      const j = await r.json().catch(() => ({}));
      if (!r.ok) { setErr(j.error || "Something went wrong."); setBusy(false); return; }
      location.reload();
    } catch (x) { setErr("Network error — please try again."); setBusy(false); }
  };
  const soon = () => setErr("Google & Apple sign-in are coming soon — use email for now.");
  const deck = [
    { id: "e2", label: "Breaking Borders" },
    { id: "e1", label: "Karan Aujla" },
    { id: "e3", label: "Kirtan Darbar" },
  ];
  return (
    <div className="auth-overlay full" onClick={onClose}>
      <div className="auth-split" onClick={(e) => e.stopPropagation()}>
        <button className="auth-x" onClick={onClose} aria-label="Close"><Icon name="x" size={20} /></button>

        <aside className="auth-aside">
          <span className="logo-word serif auth-word light"><span style={{ color: "var(--accent)" }}>i</span>Panj-<span style={{ color: "#6FB6BE" }}>āb</span></span>
          <div className="auth-deck" aria-hidden="true">
            {deck.map((d, i) => (
              <div key={d.id} className={"auth-deck-card adk-" + i}>
                <Cover seed={d.id} aspect="3 / 4" radius="18px">
                  <div className="adk-foot"><b className="serif">{d.label}</b></div>
                </Cover>
              </div>
            ))}
          </div>
          <div className="auth-aside-copy">
            <span className="kicker light">Worldwide · est. 2026</span>
            <h2 className="serif auth-aside-title">Punjab,<br /><span className="italic" style={{ color: "var(--accent)" }}>gathered</span> in one place.</h2>
            <div className="auth-aside-stat">
              <div className="ava-stack">
                {["amritsari_tadka", "8pm_vibes", "stopper_singh", "newin_brampton"].map(s => <Avatar key={s} seed={s} label={s} size={32} ring={false} />)}
              </div>
              <p><b>50,000+ in the sangat</b> hosting melas, kirtans &amp; shows worldwide.</p>
            </div>
          </div>
        </aside>

        <div className="auth-panel">
          <div className="auth-panel-top">
            <span className="logo-word serif"><span style={{ color: "var(--accent)" }}>i</span>Panj-<span style={{ color: "var(--teal, #37606B)" }}>āb</span></span>
            <span className="auth-switch-top">
              {isReg
                ? <>Have an account? <button type="button" onClick={() => { setMode("login"); setErr(""); }}>Sign in</button></>
                : <>New here? <button type="button" onClick={() => { setMode("register"); setErr(""); }}>Create one</button></>}
            </span>
          </div>

          <div className="auth-panel-body">
            <h1 className="serif auth-title">{isReg ? "Join iPanj-āb" : "Sign in to iPanj-āb"}</h1>
            <p className="auth-sub">{isReg ? "Create an account to host events, write stories and join the sangat." : "Pick up where you left off with events and threads worldwide."}</p>

            <div className="auth-social">
              <button type="button" className="auth-soc" onClick={soon}>
                <svg width="18" height="18" viewBox="0 0 18 18" aria-hidden="true"><path fill="#4285F4" d="M17.64 9.2c0-.64-.06-1.25-.16-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.72v2.26h2.92a8.78 8.78 0 0 0 2.68-6.62z"/><path fill="#34A853" d="M9 18c2.43 0 4.47-.8 5.96-2.18l-2.92-2.26c-.81.54-1.84.86-3.04.86-2.34 0-4.32-1.58-5.03-3.7H.96v2.34A9 9 0 0 0 9 18z"/><path fill="#FBBC05" d="M3.97 10.72a5.4 5.4 0 0 1 0-3.44V4.94H.96a9 9 0 0 0 0 8.12l3.01-2.34z"/><path fill="#EA4335" d="M9 3.58c1.32 0 2.5.46 3.44 1.35l2.58-2.58A9 9 0 0 0 9 0 9 9 0 0 0 .96 4.94l3.01 2.34C4.68 5.16 6.66 3.58 9 3.58z"/></svg>
                Continue with Google
              </button>
              <button type="button" className="auth-soc" onClick={soon}>
                <svg width="16" height="18" viewBox="0 0 16 18" fill="currentColor" aria-hidden="true"><path d="M13.5 9.55c0-1.86 1.52-2.75 1.59-2.8-.87-1.27-2.22-1.45-2.7-1.47-1.15-.12-2.24.68-2.82.68-.58 0-1.48-.66-2.43-.64-1.25.02-2.4.73-3.05 1.85-1.3 2.26-.33 5.6.93 7.43.62.9 1.35 1.9 2.31 1.86.93-.04 1.28-.6 2.4-.6 1.12 0 1.44.6 2.42.58 1-.02 1.63-.91 2.24-1.81.7-1.04.99-2.05 1-2.1-.02-.01-1.92-.74-1.94-2.93zM11.6 3.8c.51-.62.86-1.48.76-2.34-.74.03-1.63.49-2.16 1.11-.47.55-.89 1.43-.78 2.27.82.07 1.66-.42 2.18-1.04z"/></svg>
                Continue with Apple
              </button>
            </div>

            <div className="auth-or"><span>or with email</span></div>

            <form className="auth-form" onSubmit={submit}>
              {isReg && (
                <label className="auth-field"><span>Name</span>
                  <div className="auth-input-wrap"><Icon name="users" size={17} className="auth-in-icon" /><input className="auth-input" placeholder="What should we call you?" value={name} onChange={e => setName(e.target.value)} /></div>
                </label>
              )}
              <label className="auth-field"><span>Email</span>
                <div className="auth-input-wrap"><Icon name="globe" size={17} className="auth-in-icon" /><input className="auth-input" type="email" placeholder="you@example.com" value={email} onChange={e => setEmail(e.target.value)} required /></div>
              </label>
              <label className="auth-field">
                <div className="auth-field-row"><span>Password</span>{!isReg && <span className="auth-forgot">Forgot?</span>}</div>
                <div className="auth-input-wrap"><Icon name="lock" size={17} className="auth-in-icon" /><input className="auth-input" type={showPw ? "text" : "password"} placeholder={isReg ? "At least 6 characters" : "Your password"} value={pw} onChange={e => setPw(e.target.value)} required /><button type="button" className="auth-eye" onClick={() => setShowPw(!showPw)} aria-label="Show password"><Icon name="eye" size={18} /></button></div>
              </label>
              {!isReg && <label className="auth-keep"><input type="checkbox" defaultChecked /> <span>Keep me signed in</span></label>}
              {err && <div className="auth-err">{err}</div>}
              <button className="btn btn-primary auth-submit" disabled={busy} type="submit">{busy ? "Please wait…" : (isReg ? "Create account" : "Sign in")} <Icon name="arrowRight" size={16} /></button>
            </form>

            <p className="auth-fine">Punjabi events, culture &amp; community — worldwide.</p>
          </div>
        </div>
      </div>
    </div>
  );
}

const NAV = [
  { id: "discover", label: "Discover", icon: "compass" },
  { id: "community", label: "Community", icon: "chat" },
  { id: "read", label: "Read", icon: "book" },
];

function Nav({ route, go }) {
  const top = route.split("/")[0];
  const [menu, setMenu] = useState(false);
  const [notif, setNotif] = useState(false);
  const wrapRef = useRef(null);
  const user = (typeof window !== "undefined" && window.__USER__) || null;
  const [auth, setAuth] = useState(false);
  const [locOpen, setLocOpen] = useState(false);
  let city = "Worldwide";
  try { city = localStorage.getItem("ipanjab_city") || "Worldwide"; } catch (e) {}
  const cities = ["Worldwide", ...Array.from(new Set((window.EVENTS || []).map(e => e.dist).filter(Boolean)))];
  const setCity = (c) => { try { c === "Worldwide" ? localStorage.removeItem("ipanjab_city") : localStorage.setItem("ipanjab_city", c); } catch (e) {} location.reload(); };
  useEffect(() => {
    const onDoc = (e) => { if (wrapRef.current && !wrapRef.current.contains(e.target)) { setMenu(false); setNotif(false); setLocOpen(false); } };
    const onAuth = () => setAuth(true);
    document.addEventListener("click", onDoc);
    document.addEventListener("ipanjab:auth", onAuth);
    return () => { document.removeEventListener("click", onDoc); document.removeEventListener("ipanjab:auth", onAuth); };
  }, []);
  const nav = (r) => { setMenu(false); setNotif(false); go(r); };
  return (
    <header className="nav">
      <div className="shell nav-inner">
        <Logo onClick={() => go("discover")} />
        <nav className="nav-links">
          {NAV.map(n => (
            <button key={n.id} className="nav-link" data-on={top === n.id}
              onClick={() => go(n.id)}>
              <span>{n.label}</span>
              <span className="nav-ink" />
            </button>
          ))}
        </nav>
        <div className="nav-right" ref={wrapRef}>
          <div className="nav-pop-wrap">
            <button className="nav-loc" title="Change location" onClick={(e) => { e.stopPropagation(); setLocOpen(!locOpen); setMenu(false); setNotif(false); }}>
              <Icon name="pin" size={15} />
              <span>{city}</span>
            </button>
            {locOpen && (
              <div className="pop loc-pop" onClick={(e) => e.stopPropagation()}>
                <div className="pop-head"><b>Choose a location</b></div>
                <div className="loc-list">
                  {cities.map(c => (
                    <button key={c} className="loc-item" data-on={c === city} onClick={() => setCity(c)}>
                      <Icon name="pin" size={15} /><span>{c}</span>{c === city && <Icon name="check" size={15} className="loc-check" />}
                    </button>
                  ))}
                </div>
              </div>
            )}
          </div>
          <button className="nav-icon" aria-label="Search"><Icon name="search" size={18} /></button>
          {user && (
            <div className="nav-pop-wrap">
              <button className="nav-icon" aria-label="Notifications" data-on={notif}
                onClick={(e) => { e.stopPropagation(); setNotif(!notif); setMenu(false); }}>
                <Icon name="bell" size={18} /><span className="nav-dot" />
              </button>
              {notif && <NotifMenu go={nav} />}
            </div>
          )}
          <button className="btn btn-primary nav-host" onClick={() => (user ? go("host") : setAuth(true))}>
            <Icon name="plus" size={16} /> Host
          </button>
          {user ? (
            <div className="nav-pop-wrap">
              <button className="nav-ava-btn" onClick={(e) => { e.stopPropagation(); setMenu(!menu); setNotif(false); }} aria-label="Account">
                <Avatar seed={user.email} label={user.name} size={34} />
              </button>
              {menu && <UserMenu go={nav} user={user} />}
            </div>
          ) : (
            <button className="btn btn-soft nav-login" onClick={() => setAuth(true)}>Log in</button>
          )}
        </div>
      </div>
      {auth && <AuthModal onClose={() => setAuth(false)} />}
    </header>
  );
}

const NOTIFS = [
  { who: "Desi Beats", seed: "DB", txt: "replied to your comment on Bhangra & Giddha Night", time: "12m", unread: true },
  { who: "Gurdwara Committee", seed: "GC", txt: "confirmed your seva slot for langar on Sunday", time: "1h", unread: true },
  { who: "askpunjab", seed: "askpunjab", txt: "Your post hit 500 upvotes 🎉", time: "3h", unread: false },
  { who: "Reel Punjab", seed: "RP", txt: "‘Chann Pardesi’ screening is this Friday — doors at 7:30", time: "5h", unread: false },
];

function NotifMenu({ go }) {
  const source = (typeof window !== "undefined" && window.__DATA__ && window.__DATA__.notifs && window.__DATA__.notifs.length) ? window.__DATA__.notifs : NOTIFS;
  const [items, setItems] = useState(() => source.map(n => ({ ...n })));
  const open = (n, i) => { setItems(items.map((x, j) => j === i ? { ...x, unread: false } : x)); go(n.link || "community"); };
  return (
    <div className="pop notif-pop" onClick={(e) => e.stopPropagation()}>
      <div className="pop-head">
        <b>Notifications</b>
        <button className="pop-clear" onClick={() => setItems(items.map(n => ({ ...n, unread: false })))}>Mark all read</button>
      </div>
      <div className="notif-list">
        {items.length === 0 && <div className="notif-empty">No activity yet.</div>}
        {items.map((n, i) => (
          <button key={i} className="notif-item" data-unread={n.unread} onClick={() => open(n, i)}>
            <Avatar seed={n.seed} label={n.who} size={36} />
            <div className="notif-txt"><span><b>{n.who}</b> {n.txt}</span><i>{n.time}</i></div>
            {n.unread && <span className="notif-unread" />}
          </button>
        ))}
      </div>
      <button className="pop-foot" onClick={() => go("community")}>View all activity</button>
    </div>
  );
}

const MENU_ITEMS = [
  { id: "profile", label: "Your profile", icon: "compass", sub: "@you" },
  { id: "profile/saved", label: "Saved", icon: "bookmark" },
  { id: "host", label: "Host an event", icon: "plus" },
  { id: "settings", label: "Settings", icon: "sliders" },
];

function UserMenu({ go, user }) {
  const u = user || { name: "You", email: "you@ipanjab.com" };
  const logout = async () => { try { await fetch("/api/logout", { method: "POST" }); } catch (e) {} location.reload(); };
  return (
    <div className="pop user-pop" onClick={(e) => e.stopPropagation()}>
      <button className="user-pop-head" onClick={() => go("profile")}>
        <Avatar seed={u.email} label={u.name} size={44} />
        <div><b>{u.name}</b><span>{u.email}</span></div>
      </button>
      <div className="hr" />
      <div className="user-pop-list">
        {MENU_ITEMS.map(m => (
          <button key={m.id} className="user-pop-item" onClick={() => go(m.id)}>
            <Icon name={m.icon} size={17} />
            <span>{m.label}</span>
          </button>
        ))}
      </div>
      <div className="hr" />
      <button className="user-pop-item muted" onClick={logout}><Icon name="x" size={17} /><span>Sign out</span></button>
    </div>
  );
}

// Upvote pill — talks to /api/like when given a real target (type + id)
function VoteCluster({ initial, type, id, liked: likedProp }) {
  const [v, setV] = useState(initial || 0);
  const [liked, setLiked] = useState(!!likedProp);
  const [bump, setBump] = useState(false);
  const server = !!type && id != null;
  const up = async (e) => {
    e.stopPropagation();
    setBump(true); setTimeout(() => setBump(false), 280);
    if (server) {
      if (!(typeof window !== "undefined" && window.__USER__)) { document.dispatchEvent(new CustomEvent("ipanjab:auth")); return; }
      const wasLiked = liked, prev = v;
      setLiked(!wasLiked); setV(wasLiked ? prev - 1 : prev + 1); // optimistic
      try {
        const r = await fetch("/api/like", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ type, id }) });
        const j = await r.json();
        if (r.ok) { setV(j.count); setLiked(j.liked); } else { setLiked(wasLiked); setV(prev); }
      } catch (_) { setLiked(wasLiked); setV(prev); }
    } else {
      setLiked(l => { setV(x => l ? x - 1 : x + 1); return !l; });
    }
  };
  return (
    <div className="votes" data-bump={bump}>
      <button className="vote-btn" data-on={liked} onClick={up} aria-label="Upvote"><Icon name="arrowUp" size={18} /></button>
      <span className="vote-n">{v >= 1000 ? (v / 1000).toFixed(1) + "k" : v}</span>
    </div>
  );
}

// Scroll-reveal wrapper. Visible by default; only hides-to-animate once the
// animation engine is confirmed live (html.anim). CSS handles the transition.
function Reveal({ children, className = "", style = {} }) {
  const ref = useRef(null);
  const [shown, setShown] = useState(false);
  useEffect(() => {
    const el = ref.current; if (!el) return;
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { setShown(true); io.disconnect(); }
    }, { threshold: 0.12, rootMargin: "0px 0px -8% 0px" });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return (
    <div ref={ref} className={"reveal " + (shown ? "shown " : "") + className} style={style}>
      {children}
    </div>
  );
}

Object.assign(window, { Avatar, Cover, Logo, Nav, NAV, VoteCluster, Reveal, avaColor });
