/* ===== hub.jsx — Nexus FP&A landing: login + function launcher ===== */
const { useState, useEffect } = React;

const sb = window.supabase.createClient(window.SUPABASE_URL, window.SUPABASE_ANON_KEY, {
  auth: { persistSession: true, autoRefreshToken: true },
});

function Splash({ note }) {
  return (
    <div className="splash">
      <div className="splash-logo brand"><img src="logo.png" alt="" /></div>
      <div className="splash-t">Nexus FP&amp;A</div>
      <div className="splash-s">{note || "Loading…"}</div>
    </div>
  );
}

function Login() {
  const [email, setEmail] = useState("");
  const [pw, setPw] = useState("");
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState(null);
  async function submit(e) {
    e.preventDefault();
    setBusy(true); setErr(null);
    const { error } = await sb.auth.signInWithPassword({ email: email.trim(), password: pw });
    if (error) { setErr(error.message || "Sign-in failed"); setBusy(false); }
  }
  return (
    <div className="login-stage">
      <form className="login-card" onSubmit={submit}>
        <div className="login-brand">
          <div className="sb-logo brand" style={{ width: 40, height: 40 }}><img src="logo.png" alt="" /></div>
          <div>
            <div className="login-title">Nexus FP&amp;A</div>
            <div className="login-sub">Nexus Frontier Tech</div>
          </div>
        </div>
        <div className="login-h">Sign in to continue</div>
        <label className="login-lbl">Email</label>
        <input className="login-in" type="email" value={email} autoFocus autoComplete="username"
          onChange={(e) => setEmail(e.target.value)} placeholder="you@nexusfrontier.tech" />
        <label className="login-lbl">Password</label>
        <input className="login-in" type="password" value={pw} autoComplete="current-password"
          onChange={(e) => setPw(e.target.value)} placeholder="••••••••" />
        {err && <div className="login-err">{err}</div>}
        <button className="btn btn-primary login-btn" type="submit" disabled={busy || !email || !pw}>
          {busy ? <><span className="spinner" />Signing in…</> : "Sign in"}
        </button>
        <div className="login-foot">Confidential — authorised users only</div>
      </form>
    </div>
  );
}

function Hub({ session, onSignOut }) {
  const email = (session && session.user && session.user.email) || "";
  const [access, setAccess] = useState(undefined);
  useEffect(() => {
    let cancelled = false;
    sb.from("user_access").select("hubs,is_admin").eq("email", email).maybeSingle().then(({ data }) => {
      if (!cancelled) setAccess(data || { hubs: [], is_admin: false });
    });
    return () => { cancelled = true; };
  }, [email]);
  const fns = [
    {
      key: "budget",
      title: "Budget & Variance",
      tagline: "Plan, track, reforecast",
      desc: "Plan, track, and reforecast against budget each quarter.",
      href: "Budget & Variance.html",
      status: "Live",
      icon: IconBudget,
      tag: "Finance",
    },
    {
      key: "boardpack",
      title: "Board Pack",
      tagline: "Tell the story to the board",
      desc: "Turn the numbers into a clean, presentable board pack.",
      href: "Nexus Board Pack Generator.html",
      status: "In Progress",
      icon: IconDeck,
      tag: "Reporting",
    },
    {
      key: "ar",
      title: "AR Tracker",
      tagline: "Invoices, collections, cash-in",
      desc: "Track every invoice from issue to collection, with a weekly Slack digest.",
      href: "AR Tracker.html",
      status: "Live",
      icon: IconAR,
      tag: "Operating",
    },
    {
      key: "tasks",
      title: "Finance Task Tracker",
      tagline: "Track what needs doing",
      desc: "A shared task table with status, deadlines and notes, synced to the cloud.",
      href: "Hana Tasks.html",
      status: "Live",
      icon: IconTasks,
      tag: "Operating",
    },
    {
      key: "consol",
      title: "Consolidated Reporting",
      tagline: "Group BS & PnL across entities",
      desc: "Consolidate UK, SG and JP into one Balance Sheet and P&L, with intercompany eliminations and FX translation handled for you.",
      href: "Consolidated Reporting.html",
      status: "In Progress",
      icon: IconConsol,
      tag: "Reporting",
    },
  ];
  const sortedFns = [...fns].sort((a, b) => (a.status === "In Progress") - (b.status === "In Progress"));
  const allowed = (key) => !access || access.is_admin || (access.hubs || []).includes(key);
  if (access === undefined) return <Splash note="Checking your access…" />;
  return (
    <div className="hub">
      <header className="hub-top">
        <div className="hub-brand">
          <div className="sb-logo brand"><img src="logo.png" alt="" /></div>
          <div>
            <div className="hub-name">Nexus FP&amp;A</div>
            <div className="hub-org">Nexus Frontier Tech</div>
          </div>
        </div>
        <div className="hub-user">
          <span className="hub-email">{email}</span>
          <button className="btn btn-ghost" onClick={onSignOut}>Sign out</button>
        </div>
      </header>

      <main className="hub-main">
        <div className="hub-hero">
          <h1>Financial planning &amp; analysis</h1>
          <p>One workspace, one source of truth.</p>
        </div>

        <div className="hub-cards">
          {sortedFns.map((f) => {
            const live = !!f.href && allowed(f.key);
            const locked = !!f.href && !allowed(f.key);
            const Card = live ? "a" : "div";
            return (
              <Card key={f.key} className={"fn-card" + (live ? "" : " disabled") + (locked ? " locked" : "")} href={f.href || undefined}>
                <div className="fn-top">
                  <div className="fn-icon">{f.icon}</div>
                  <span className="fn-status-wrap">
                    {(f.key === "ar" || f.key === "tasks") && <span className="fn-star">★</span>}
                    <span className={"fn-status " + (f.status === "In Progress" ? "preview" : live ? "live" : "soon")}>{f.status}</span>
                  </span>
                </div>
                <div className="fn-title">{f.title}</div>
                <div className="fn-tagline">{f.tagline}</div>
                <p className="fn-desc">{f.desc}</p>
                <div className="fn-bottom">
                  <span className="fn-tag">{f.tag}</span>
                  <span className="fn-cta">{locked ? <>{IconLock} Restricted</> : live ? <>Open {IconArrow}</> : "Not yet available"}</span>
                </div>
              </Card>
            );
          })}
        </div>
      </main>
    </div>
  );
}

function Root() {
  const [session, setSession] = useState(undefined);
  useEffect(() => {
    sb.auth.getSession().then(({ data }) => setSession(data.session));
    const { data: sub } = sb.auth.onAuthStateChange((_e, s) => setSession(s));
    return () => sub.subscription.unsubscribe();
  }, []);
  if (session === undefined) return <Splash note="Checking your session…" />;
  if (!session) return <Login />;
  return <Hub session={session} onSignOut={() => sb.auth.signOut()} />;
}

const IconBudget = <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="3" y1="20" x2="21" y2="20"/><rect x="5" y="10" width="3.2" height="8"/><rect x="10.4" y="5" width="3.2" height="13"/><rect x="15.8" y="13" width="3.2" height="5"/></svg>;
const IconDeck = <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="4" width="18" height="13" rx="2"/><line x1="9" y1="21" x2="15" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>;
const IconTasks = <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="9 11 12 14 22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg>;
const IconAR = <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="5" width="18" height="14" rx="2"/><line x1="3" y1="10" x2="21" y2="10"/><line x1="7" y1="15" x2="11" y2="15"/></svg>;
const IconConsol = <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="8" cy="9" r="5"/><circle cx="16" cy="15" r="5"/></svg>;
const IconArrow = <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>;
const IconLock = <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><rect x="5" y="11" width="14" height="10" rx="2"/><path d="M8 11V7a4 4 0 0 1 8 0v4"/></svg>;

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