// dashboard.jsx — logged-in app shell (routes tab screens from dash-tabs.jsx)
const { useState: useStateD, useRef: useRefD, useEffect: useEffectD } = React;

const NAV = [
  ["Overview", "grid"], ["Viewer Bot", "signal"], ["Chat Bot", "chat"],
  ["Ai Chatbot", "spark"], ["Poll Bot", "poll"], ["Follow Bot", "users"],
  ["Clip Viewbot", "scissors"],
  ["Chat Scraper", "chat"],
  ["KCIP Fix", "chart"],
  ["Billing", "card"], ["Settings", "gauge"],
];
const NAV_GROUPS = [
  ["", ["Overview"]],
  ["BOTS", ["Viewer Bot", "Chat Bot", "Ai Chatbot", "Poll Bot", "Follow Bot", "Clip Viewbot"]],
  ["SERVICES", ["Chat Scraper", "KCIP Fix"]],
  ["ACCOUNT", ["Billing", "Settings"]],
];
const ICON_OF = Object.fromEntries(NAV);

// Nav items that should wear a glowing "NEW!" pill. Remove the entry once it stops being new.
const NEW_NAV = { "Chat Scraper": true };

// Styling is inline (not styles.css) on purpose: styles.css is served with no Cache-Control, so a
// returning customer can hold a stale copy and the badge would render as bare text. The bundle is
// content-hashed, so shipping the look in here guarantees it matches the markup.
const NEW_BADGE = {
  flexShrink: 0, fontSize: 9, fontWeight: 800, letterSpacing: "0.06em", lineHeight: 1,
  padding: "3px 6px", borderRadius: 999, color: "var(--accent-ink)",
  background: "linear-gradient(160deg, var(--accent), var(--accent-deep))",
  animation: "kvbNewGlow 1.9s ease-in-out infinite",
};

// Keyframes have to live in a stylesheet, so inject them once from the bundle itself.
// prefers-reduced-motion is honoured - the pill stays, only the pulsing stops.
if (typeof document !== "undefined" && !document.getElementById("kvb-new-badge-css")) {
  const kvbNewCss = document.createElement("style");
  kvbNewCss.id = "kvb-new-badge-css";
  kvbNewCss.textContent =
    "@keyframes kvbNewGlow{"
  +   "0%,100%{box-shadow:0 0 4px 0 var(--accent-glow);transform:scale(1)}"
  +   "50%{box-shadow:0 0 13px 3px var(--accent-glow);transform:scale(1.07)}"
  + "}"
  + "@media (prefers-reduced-motion:reduce){"
  +   "[data-kvb-new]{animation:none !important}"
  + "}";
  document.head.appendChild(kvbNewCss);
}

function Dashboard({ onNav, preview }) {
  const [active, setActive] = useStateD(() => {
    // Deep-link the initial tab via ?go=<Tab> (e.g. a KCIP marketing CTA → ?go=KCIP%20Fix).
    try { var g = new URLSearchParams(window.location.search).get("go"); if (g && window.SCREENS && window.SCREENS[g]) return g; } catch (e) {}
    return "Overview";
  });
  const [profileOpen, setProfileOpen] = useStateD(false); // topbar avatar dropdown
  const Screen = (window.SCREENS && window.SCREENS[active]) || (() => null);

  // Announcement banner for a newly shipped feature. Dismissal is remembered per browser.
  const [showNewBanner, setShowNewBanner] = useStateD(function () {
    try { return localStorage.getItem("kvb_banner_scraper") !== "1"; } catch (e) { return true; }
  });
  function dismissNewBanner() {
    setShowNewBanner(false);
    try { localStorage.setItem("kvb_banner_scraper", "1"); } catch (e) {}
  }
  // Topbar avatar: real uploaded picture, else gravatar (same rule as Settings + the
  // original dashboard.php), else the "K" initial as a last resort.
  const KVB_D = window.__KVB || {};
  const avatarUrl = KVB_D.profilePicture
    || (KVB_D.emailHash ? ("https://www.gravatar.com/avatar/" + KVB_D.emailHash + "?d=mp") : null);

  return (
    <div style={{ minHeight: preview ? 0 : "100vh", height: preview ? "100%" : undefined, position: "relative", zIndex: 1, display: "grid", gridTemplateColumns: "252px 1fr" }} className={"dash-grid" + (preview ? " dash-preview" : "")}>
      {/* Sidebar */}
      <aside className="glass" style={{ margin: 14, marginRight: 0, borderRadius: "var(--radius)", padding: 16, display: "flex", flexDirection: "column", position: preview ? "relative" : "sticky", top: preview ? 0 : 14, height: preview ? "auto" : "calc(100vh - 28px)" }}>
        <div style={{ padding: "6px 8px 16px" }}><Logo size={26} onClick={() => onNav("landing")} /></div>
        <nav className="stack" style={{ gap: 3, flex: 1, overflowY: "auto" }}>
          {NAV_GROUPS.map(([group, items]) => (
            <div key={group || "top"} style={{ marginTop: group ? 16 : 0 }}>
              {group && <div className="cap" style={{ fontSize: 10.5, letterSpacing: "0.12em", padding: "0 12px 8px", color: "var(--ink-3)" }}>{group}</div>}
              <div className="stack" style={{ gap: 3 }}>
                {items.map(label => {
                  const on = active === label;
                  return (
                    <button key={label} onClick={() => setActive(label)} style={{
                      display: "flex", alignItems: "center", gap: 12, padding: "10px 12px", borderRadius: 11, border: "none", cursor: "pointer",
                      background: on ? "linear-gradient(160deg, color-mix(in oklch, var(--accent) 24%, transparent), color-mix(in oklch, var(--accent) 7%, transparent))" : "transparent",
                      color: on ? "var(--ink)" : "var(--ink-2)", textAlign: "left", fontSize: 14, fontWeight: on ? 560 : 460,
                      boxShadow: on ? "inset 0 0 0 1px color-mix(in oklch, var(--accent) 32%, transparent)" : "none", transition: "background .2s, color .2s",
                    }}
                      onMouseEnter={e => { if (!on) e.currentTarget.style.background = "var(--glass-fill)"; }}
                      onMouseLeave={e => { if (!on) e.currentTarget.style.background = "transparent"; }}>
                      <span style={{ color: on ? "var(--accent)" : "var(--ink-3)" }}><DIcon name={ICON_OF[label]} size={18} /></span>{label}{!on && NEW_NAV[label] && <span data-kvb-new style={{ ...NEW_BADGE, marginLeft: "auto" }}>NEW!</span>}
                    </button>
                  );
                })}
              </div>
            </div>
          ))}
        </nav>
        <div className="glass" style={{ padding: 14, borderRadius: 14, marginTop: 12 }}>
          <div className="cap">YOUR CREDITS</div>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", margin: "4px 0 10px" }}>
            <span style={{ fontWeight: 700, fontSize: 20, letterSpacing: "-0.02em" }}>{Number((((typeof window !== "undefined" && window.__KVB) || {}).balSum) || 0).toLocaleString()}</span>
            <span className="cap">total credits</span>
          </div>
          <a href="add-balance.php" className="btn btn-primary btn-sm" style={{ width: "100%", justifyContent: "center", textDecoration: "none" }}>Add balance</a>
        </div>
      </aside>

      {/* Main */}
      <main style={{ padding: 14, minWidth: 0 }}>
        {/* Mobile tab nav (sidebar is hidden on small screens) */}
        {!preview && (
        <nav className="dash-mobnav" style={{ display: "none", gap: 7, overflowX: "auto", paddingBottom: 12, marginBottom: 2, WebkitOverflowScrolling: "touch" }}>
          {NAV.map(([label, icon]) => {
            const on = active === label;
            return (
              <button key={label} onClick={() => setActive(label)} style={{
                display: "inline-flex", alignItems: "center", gap: 8, flexShrink: 0, whiteSpace: "nowrap",
                padding: "9px 14px", borderRadius: 999, cursor: "pointer", fontSize: 13.5, fontWeight: on ? 600 : 500,
                background: on ? "linear-gradient(160deg, var(--accent), var(--accent-deep))" : "var(--glass-fill)",
                color: on ? "var(--accent-ink)" : "var(--ink-2)",
                border: on ? "none" : "1px solid var(--glass-border)",
              }}>
                <DIcon name={icon} size={15} /> {label}{!on && NEW_NAV[label] && <span data-kvb-new style={{ ...NEW_BADGE, marginLeft: 6 }}>NEW!</span>}
              </button>
            );
          })}
        </nav>
        )}
        {/* Topbar */}
        <div className="glass dash-topbar" style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "10px 14px 10px 18px", borderRadius: "var(--radius)", marginBottom: 14, position: "relative", zIndex: 40 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 11, minWidth: 0 }}>
            <span style={{ color: "var(--accent)", flexShrink: 0 }}><DIcon name={ICON_OF[active]} size={18} /></span>
            <span className="h3" style={{ fontWeight: 560, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{active}</span>
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 10, flexShrink: 0 }}>
            <div className="status ok dash-engine" style={{ padding: "6px 12px" }}><span className="sd live-dot" /> Engine online</div>
            <div style={{ position: "relative" }}>
              <div title="Account" onClick={() => setProfileOpen(o => !o)} style={{ width: 36, height: 36, borderRadius: "50%", overflow: "hidden", background: "linear-gradient(150deg, var(--accent), var(--accent-deep))", display: "grid", placeItems: "center", color: "var(--accent-ink)", fontWeight: 700, fontSize: 14, cursor: "pointer", flexShrink: 0, boxShadow: profileOpen ? "0 0 0 3px var(--accent-glow)" : "none", transition: "box-shadow .2s" }}>
                {avatarUrl
                  ? <img src={avatarUrl} alt="" style={{ width: "100%", height: "100%", objectFit: "cover" }}
                      onError={e => { e.currentTarget.style.display = "none"; e.currentTarget.parentNode.appendChild(document.createTextNode("K")); }} />
                  : "K"}
              </div>
              {profileOpen && (
                <React.Fragment>
                  {/* click-catcher to close on outside click */}
                  <div onClick={() => setProfileOpen(false)} style={{ position: "fixed", inset: 0, zIndex: 60 }} />
                  <div className="glass-strong" style={{ position: "absolute", top: "calc(100% + 10px)", right: 0, width: 260, borderRadius: "var(--radius)", padding: 16, zIndex: 80, boxShadow: "var(--shadow-float)", background: "color-mix(in oklch, var(--bg-1) 92%, black)", backdropFilter: "blur(calc(var(--glass-blur) + 8px)) saturate(160%)", WebkitBackdropFilter: "blur(calc(var(--glass-blur) + 8px)) saturate(160%)" }}>
                    <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 14 }}>
                      <div style={{ width: 44, height: 44, borderRadius: "50%", flexShrink: 0, overflow: "hidden", background: "linear-gradient(150deg, var(--accent), var(--accent-deep))", display: "grid", placeItems: "center", color: "var(--accent-ink)", fontWeight: 700, fontSize: 18 }}>
                        {avatarUrl ? <img src={avatarUrl} alt="" style={{ width: "100%", height: "100%", objectFit: "cover" }} /> : "K"}
                      </div>
                      <div style={{ minWidth: 0 }}>
                        <div style={{ fontWeight: 600, fontSize: 14, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{KVB_D.email || "Your account"}</div>
                        <div className="cap" style={{ fontSize: 11.5 }}><span style={{ color: "var(--accent)" }}>{KVB_D.plan ? KVB_D.plan + " plan" : "Free plan"}</span></div>
                      </div>
                    </div>
                    {/* one REAL stat (the designer's mock stats are intentionally dropped) */}
                    <div className="stack" style={{ gap: 1, borderRadius: 12, overflow: "hidden", border: "1px solid var(--glass-border-soft)", marginBottom: 14 }}>
                      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", gap: 10, padding: "10px 12px", background: "color-mix(in oklch, black 18%, transparent)" }}>
                        <span className="cap" style={{ fontSize: 11.5 }}>Total credits</span>
                        <span style={{ fontSize: 13, fontWeight: 600, fontVariantNumeric: "tabular-nums" }}>{Number(KVB_D.balSum || 0).toLocaleString()}</span>
                      </div>
                    </div>
                    <button className="btn btn-ghost btn-sm" onClick={() => { setProfileOpen(false); setActive("Settings"); }} style={{ width: "100%", justifyContent: "center", marginBottom: 8 }}>Account settings</button>
                    {/* REAL logout (kills the session) — NOT the designer's fake onNav("landing") */}
                    <button className="btn btn-ghost btn-sm" onClick={() => { setProfileOpen(false); window.location.href = "api/authentication/logout.php"; }} style={{ width: "100%", justifyContent: "center" }}>Log out</button>
                  </div>
                </React.Fragment>
              )}
            </div>
          </div>
        </div>

        {!preview && showNewBanner && active !== "Chat Scraper" && (
          <div className="kvb-banner glass" style={{
            position: "relative", overflow: "hidden", borderRadius: "var(--radius)", marginBottom: 14,
            padding: "14px 18px", display: "flex", alignItems: "center", gap: 14, flexWrap: "wrap",
            border: "1px solid color-mix(in oklch, var(--accent) 34%, transparent)",
            background: "linear-gradient(120deg, color-mix(in oklch, var(--accent) 17%, transparent), color-mix(in oklch, var(--accent) 4%, transparent))",
          }}>
            <span className="kvb-banner-sheen" style={{
              position: "absolute", inset: 0, pointerEvents: "none",
              background: "linear-gradient(100deg, rgba(255,255,255,0) 38%, rgba(255,255,255,0.16) 50%, rgba(255,255,255,0) 62%)",
              backgroundSize: "250% 100%",
              backgroundRepeat: "no-repeat",
            }} />
            <span style={{
              width: 38, height: 38, borderRadius: 11, flexShrink: 0, display: "grid", placeItems: "center",
              color: "var(--accent-ink)", background: "linear-gradient(160deg, var(--accent), var(--accent-deep))",
            }}><DIcon name="chat" size={19} /></span>
            <div style={{ flex: 1, minWidth: 210 }}>
              <div style={{ fontWeight: 700, fontSize: 15, letterSpacing: "-0.01em", display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }}>
                New: Chat Scraper
                <span data-kvb-new style={{ ...NEW_BADGE }}>FREE</span>
              </div>
              <div className="cap" style={{ marginTop: 3 }}>
                Collect real chat from any live channel into a downloadable list - or send it straight to your Chat Bot.
              </div>
            </div>
            <button className="btn btn-primary btn-sm" onClick={() => setActive("Chat Scraper")}
              style={{ borderRadius: 999, flexShrink: 0, position: "relative" }}>
              Try it now
            </button>
            <button type="button" onClick={dismissNewBanner} title="Dismiss" aria-label="Dismiss this announcement"
              style={{
                flexShrink: 0, position: "relative", background: "transparent", border: "none", cursor: "pointer",
                color: "var(--ink-3)", fontSize: 18, lineHeight: 1, padding: "4px 6px",
              }}
              onMouseEnter={e => e.currentTarget.style.color = "var(--ink)"}
              onMouseLeave={e => e.currentTarget.style.color = "var(--ink-3)"}>
              {"\u00d7"}
            </button>
          </div>
        )}

        <div key={active} className="dash-screen">
          <Screen go={setActive} />
        </div>
      </main>

      <style>{`
        /* Announcement banner: slides in once, then a slow sheen sweeps across so it
           catches the eye without the jitter of a looping bounce. */
        .kvb-banner{ animation: kvbBannerIn .55s cubic-bezier(.2,.8,.2,1) both; }
        .kvb-banner-sheen{ animation: kvbSheen 6.5s cubic-bezier(.4,0,.2,1) infinite; }
        @keyframes kvbBannerIn{ from{ opacity:0; transform: translateY(-10px); } to{ opacity:1; transform:none; } }
        /* background-position, not translateX: percentages resolve against the element, so the
           sweep crosses the full banner at ANY width. At both 150% and -50% the highlight sits
           off-canvas, so the wrap-around is invisible and it reads as one pass every ~6.5s. */
        @keyframes kvbSheen{
          0%, 6%    { background-position: 150% 0; }
          48%, 100% { background-position: -50% 0; }
        }
        @media (prefers-reduced-motion: reduce){
          .kvb-banner{ animation: none !important; }
          .kvb-banner-sheen{ display: none !important; }
        }
        @media (max-width: 1080px){
          .dash-2col{ grid-template-columns: 1fr !important; }
          .rg4{ grid-template-columns: 1fr 1fr !important; }
        }
        @media (max-width: 720px){
          .dash-grid:not(.dash-preview){ grid-template-columns: 1fr !important; }
          .dash-grid:not(.dash-preview) > aside{ display:none !important; }
          .dash-grid:not(.dash-preview) > main{ padding: 12px !important; }
          .dash-grid:not(.dash-preview) .dash-mobnav{ display:flex !important; }
          .rg4, .rg3{ grid-template-columns: 1fr 1fr !important; }
        }
        @media (max-width: 520px){
          .dash-grid:not(.dash-preview) .dash-engine{ display:none !important; }
        }
        @media (max-width: 460px){ .rg4, .rg3{ grid-template-columns: 1fr !important; } }
      `}</style>
    </div>
  );
}

/* Scaled, non-interactive render of the real dashboard for the hero window */
function DashboardPreview({ designW = 1240, designH = 760 }) {
  const wrap = useRefD(null);
  const [scale, setScale] = useStateD(0.5);
  useEffectD(() => {
    const fit = () => { if (wrap.current) setScale(wrap.current.clientWidth / designW); };
    fit();
    const ro = new ResizeObserver(fit);
    if (wrap.current) ro.observe(wrap.current);
    return () => ro.disconnect();
  }, [designW]);
  return (
    <div ref={wrap} style={{ width: "100%", height: designH * scale, overflow: "hidden", borderRadius: 14, position: "relative", background: "var(--bg-0)" }}>
      <div style={{ width: designW, height: designH, transform: `scale(${scale})`, transformOrigin: "top left", position: "absolute", top: 0, left: 0, pointerEvents: "none" }}>
        <Dashboard onNav={() => {}} preview />
      </div>
    </div>
  );
}
Object.assign(window, { DashboardPreview });
