// Primate App Kit — root interactive app
const { useState: useStateApp, useEffect: useEffectApp } = React;

// Phase 0 of the flow: the marketing site, embedded as-is. Its "Get Started" /
// "Sign In" buttons postMessage up to advance into auth (see marketing/index.html).
function Marketing({ onStart }) {
  useEffectApp(() => {
    function onMsg(e) {
      if (e.data && e.data.type === "primate-cta") onStart(e.data.intent);
    }
    window.addEventListener("message", onMsg);
    return () => window.removeEventListener("message", onMsg);
  }, [onStart]);
  return <iframe src="marketing/index.html" title="Primate" style={{ border: "none", width: "100%", height: "100%", display: "block", background: "var(--bg)" }} />;
}

function Placeholder({ title }) {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 24 }}>
      <h1 style={{ font: "var(--t-h1)", letterSpacing: "-0.02em", margin: 0 }}>{title}</h1>
      <div style={{ border: "1px dashed var(--border)", borderRadius: "var(--r-md)", background: "var(--bg-card)", padding: "64px 24px", display: "flex", flexDirection: "column", alignItems: "center", gap: 8 }}>
        <Logo size={36} fill="var(--bg-elevated-2)" />
        <div style={{ font: "var(--t-h3)", color: "var(--fg-secondary)" }}>{title}</div>
        <div style={{ font: "var(--t-body-sm)", color: "var(--fg-faint)", textAlign: "center", maxWidth: 360 }}>
          This screen isn't part of the recreated kit. The design system covers the marketing site, auth, and the Review Logs / Review Details surfaces.
        </div>
      </div>
    </div>
  );
}

function HomeEmpty() {
  return (
    <div style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 16, textAlign: "center" }}>
      <Logo size={48} fill="var(--gold)" />
      <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 4 }}>
        <div style={{ font: "var(--t-h2)", color: "var(--fg)" }}>The Jungle is Quiet</div>
        <div style={{ font: "var(--t-body)", color: "#B5B5B5", maxWidth: 380 }}>Open a PR and Primate will start exploring</div>
      </div>
    </div>
  );
}

// representative run used when the Screens panel jumps straight to Review Details
const SAMPLE_RUN = { id: 55, pr: "#138", status: "completed", commit: "a1b2c3d", repo: "jeremybell232/taskflow", branch: "more-style-fixes", when: "about 15 hours ago" };

// device frames for the Screens-panel viewport switcher. desktop = full bleed (no
// frame); tablet / mobile render the screen at true CSS width inside a bezel that
// is scaled to fit the available stage.
const DEVICES = {
  tablet: { w: 834, h: 1112, bezel: 16, radius: 38, label: "834 × 1112" },
  mobile: { w: 430, h: 932,  bezel: 14, radius: 54, label: "430 × 932" },
};

function FramedStage({ dev, children }) {
  const ref = React.useRef(null);
  const [scale, setScale] = useStateApp(1);
  const BORDER = 1;
  const frameW = dev.w + dev.bezel * 2 + BORDER * 2;
  const frameH = dev.h + dev.bezel * 2 + BORDER * 2;
  useEffectApp(() => {
    const el = ref.current;
    if (!el) return;
    const compute = () => {
      const pad = 96; // breathing room around the frame
      const s = Math.min(1, (el.clientWidth - pad) / frameW, (el.clientHeight - pad) / frameH);
      setScale(s > 0 ? s : 1);
    };
    compute();
    const ro = new ResizeObserver(compute);
    ro.observe(el);
    return () => ro.disconnect();
  }, [frameW, frameH]);

  return (
    <div ref={ref} style={{ flex: 1, minWidth: 0, height: "100vh", position: "relative", display: "flex", alignItems: "center", justifyContent: "center", overflow: "auto", background: "var(--bg-card)" }}>
      {/* wrapper reserves the SCALED footprint so flex-centering stays correct */}
      <div style={{ width: frameW * scale, height: frameH * scale, flexShrink: 0 }}>
        <div style={{
          width: frameW, height: frameH, boxSizing: "border-box", transform: `scale(${scale})`, transformOrigin: "top left",
          background: "var(--bg-elevated)", borderRadius: dev.radius, padding: dev.bezel,
          border: "1px solid var(--border)", boxShadow: "0 30px 90px rgba(0,0,0,0.55)",
        }}>
          <div className="device-screen" style={{ width: dev.w, height: dev.h, borderRadius: dev.radius - dev.bezel, overflow: "hidden", background: "var(--bg)", position: "relative", display: "flex", flexDirection: "column" }}>
            {/* mock browser chrome */}
            <div style={{ flexShrink: 0, height: 38, display: "flex", alignItems: "center", gap: 8, padding: dev.w <= 500 ? "0 14px 0 20px" : "0 14px", background: "var(--bg-card)", borderBottom: "1px solid var(--border)" }}>
              <span style={{ display: "flex", gap: 7, flexShrink: 0 }}>
                <span style={{ width: 11, height: 11, borderRadius: "50%", background: "#ff5f57" }}></span>
                <span style={{ width: 11, height: 11, borderRadius: "50%", background: "#febc2e" }}></span>
                <span style={{ width: 11, height: 11, borderRadius: "50%", background: "#28c840" }}></span>
              </span>
              <span style={{ flex: 1, display: "flex", justifyContent: "center", minWidth: 0 }}>
                <span style={{ display: "inline-flex", alignItems: "center", gap: 6, maxWidth: "100%", height: 22, padding: "0 16px", borderRadius: 999, background: "var(--bg-elevated)", border: "1px solid var(--border-subtle)", font: "var(--t-caption)", color: "var(--fg-faint)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>primate.sh</span>
              </span>
              <span style={{ width: 33, flexShrink: 0 }}></span>
            </div>
            <div style={{ flex: 1, minHeight: 0, position: "relative" }}>
              {children}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

function Stage({ viewport, children }) {
  const dev = DEVICES[viewport];
  if (!dev) {
    return <div style={{ flex: 1, minWidth: 0, height: "100vh", position: "relative" }}>{children}</div>;
  }
  return <FramedStage dev={dev}>{children}</FramedStage>;
}

// Dashboard shell: sidebar + content on desktop/tablet; a top bar + slide-in drawer
// on mobile. Reads the effective viewport from context.
function AppShell({ current, onNavigate, cardStyle, children }) {
  const vp = useViewport();
  const mobile = vp === "mobile";
  const [drawer, setDrawer] = useStateApp(false);
  useEffectApp(() => { if (!mobile && drawer) setDrawer(false); }, [mobile]);
  useEffectApp(() => { if (window.lucide) window.lucide.createIcons({ nameAttr: "data-lucide" }); }, [drawer, mobile]);

  const pad = vp === "desktop" ? 24 : 16;
  const contentArea = (
    <div style={{ flex: 1, minWidth: 0, background: "var(--bg-card)", padding: pad, overflowY: "auto", overflowX: "auto", display: "flex", flexDirection: "column" }}>
      <div style={cardStyle}>{children}</div>
    </div>
  );

  if (!mobile) {
    return (
      <div style={{ display: "flex", height: "100%", background: "var(--bg)" }}>
        <Sidebar current={current} onNavigate={onNavigate} />
        {contentArea}
      </div>
    );
  }

  return (
    <div style={{ position: "relative", display: "flex", flexDirection: "column", height: "100%", background: "var(--bg)", overflow: "hidden" }}>
      <div style={{ flexShrink: 0, height: 56, display: "flex", alignItems: "center", gap: 12, padding: "0 14px", borderBottom: "1px solid var(--border)", background: "var(--bg)" }}>
        <button onClick={() => setDrawer(true)} title="Menu"
          style={{ width: 38, height: 38, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: 8, border: "1px solid var(--border-subtle)", background: "var(--bg-elevated)", cursor: "pointer", flexShrink: 0 }}>
          <Icon name="menu" size={18} color="var(--fg)" />
        </button>
        <span style={{ width: 28, height: 28, borderRadius: 7, background: "var(--bg-elevated)", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}><Logo size={16} /></span>
        <span style={{ font: "var(--t-label)", color: "var(--fg)" }}>Acme Inc</span>
      </div>
      {contentArea}
      {drawer && (
        <div onClick={() => setDrawer(false)} style={{ position: "absolute", inset: 0, zIndex: 50, background: "rgba(0,0,0,0.55)" }}>
          <div onClick={(e) => e.stopPropagation()} style={{ position: "absolute", top: 0, left: 0, bottom: 0, width: 260, boxShadow: "var(--shadow-lg)" }}>
            <Sidebar current={current} onNavigate={(n) => { setDrawer(false); onNavigate(n); }} />
          </div>
        </div>
      )}
    </div>
  );
}

function App() {
  const [phase, setPhase] = useStateApp("marketing"); // marketing | onboarding | auth | app
  const [authMode, setAuthMode] = useStateApp("login");
  const [nav, setNav] = useStateApp("logs");
  const [openRun, setOpenRun] = useStateApp(null);
  const [onbStep, setOnbStep] = useStateApp(0);
  const [onbJump, setOnbJump] = useStateApp(0); // bump to force Onboarding to remount at onbStep
  const [viewport, setViewport] = useStateApp("desktop"); // default to full desktop on load

  // track the real window so the app also adapts when the portfolio is opened on an
  // actual phone/tablet (not just inside a device frame).
  const [winW, setWinW] = useStateApp(() => (typeof window !== "undefined" ? window.innerWidth : 1280));
  useEffectApp(() => {
    const onR = () => setWinW(window.innerWidth);
    onR();
    window.addEventListener("resize", onR);
    return () => window.removeEventListener("resize", onR);
  }, []);
  const effectiveVp = viewport !== "desktop" ? viewport : (winW < 640 ? "mobile" : winW < 1024 ? "tablet" : "desktop");

  // keep lucide icons fresh when the screen changes
  useEffectApp(() => { if (window.lucide) window.lucide.createIcons({ nameAttr: "data-lucide" }); }, [phase, nav, openRun, onbStep, viewport]);

  // a stable key for the current screen, consumed by the Screens panel
  let screenKey;
  if (phase === "marketing") screenKey = "marketing";
  else if (phase === "auth") screenKey = authMode === "login" ? "auth-login" : "auth-signup";
  else if (phase === "onboarding") screenKey = "onb-" + onbStep;
  else if (openRun !== null) screenKey = "app-details";
  else screenKey = "app-" + nav;

  // jump anywhere in the flow from the Screens panel
  function navigate(key) {
    setOpenRun(null);
    if (key === "marketing") { setPhase("marketing"); return; }
    if (key === "auth-login") { setAuthMode("login"); setPhase("auth"); return; }
    if (key === "auth-signup") { setAuthMode("signup"); setPhase("auth"); return; }
    if (key.startsWith("onb-")) { setOnbStep(Number(key.slice(4))); setOnbJump(j => j + 1); setPhase("onboarding"); return; }
    if (key === "app-details") { setOpenRun(SAMPLE_RUN); setNav("logs"); setPhase("app"); return; }
    if (key.startsWith("app-")) { setNav(key.slice(4)); setPhase("app"); return; }
  }

  const panel = <LayersPanel current={screenKey} onNavigate={navigate} viewport={viewport} onViewport={setViewport} />;
  const wrap = (screen) => (
    <ViewportCtx.Provider value={effectiveVp}>
      <div style={{ display: "flex", height: "100vh", width: "100%", overflow: "hidden" }}>
        {panel}
        <Stage viewport={viewport}>{screen}</Stage>
      </div>
    </ViewportCtx.Provider>
  );

  if (phase === "marketing") {
    return wrap(<Marketing onStart={(intent) => { setAuthMode(intent === "login" ? "login" : "signup"); setPhase("auth"); }} />);
  }
  if (phase === "onboarding") {
    return wrap(<Onboarding key={onbJump} initialStep={onbStep} onStepChange={setOnbStep} onDone={() => { setOpenRun(null); setNav("logs"); setPhase("app"); }} onBack={() => setPhase("auth")} onHome={() => setPhase("marketing")} />);
  }
  if (phase === "auth") {
    return wrap(<Auth mode={authMode} onAuthed={() => {
      if (authMode === "login") { setOpenRun(null); setNav("logs"); setPhase("app"); }
      else { setOnbStep(0); setOnbJump(j => j + 1); setPhase("onboarding"); }
    }} onSwitch={() => setAuthMode(m => m === "signup" ? "login" : "signup")} />);
  }

  let content;
  if (openRun !== null) {
    content = <ReviewDetails run={openRun} onBack={() => setOpenRun(null)} />;
  } else if (nav === "logs") {
    content = <ReviewLogs onOpen={(r) => setOpenRun(r)} onBilling={() => setNav("billing")} />;
  } else if (nav === "home") {
    content = <HomeEmpty />;
  } else if (nav === "billing") {
    content = <Billing />;
  } else if (nav === "organization") {
    content = <Organization />;
  } else {
    const titles = { billing: "Billing", organization: "Organization" };
    content = <Placeholder title={titles[nav] || "Page"} />;
  }

  // logs + home fill the viewport; on compact widths logs becomes a growing card
  // list so the page scrolls instead of the table scrolling internally.
  const isFill = openRun === null && (nav === "home" || (nav === "logs" && effectiveVp === "desktop"));
  const fullBleed = openRun === null && nav === "billing";
  const cardPad = effectiveVp === "desktop" ? 28 : effectiveVp === "tablet" ? 20 : 16;
  const cardStyle = fullBleed
    ? { flex: 1, minHeight: 0, display: "flex" }
    : {
        border: "1px solid var(--border)", borderRadius: "var(--r-md)", background: "var(--bg)", padding: cardPad, display: "flex", flexDirection: "column",
        ...(isFill ? { flex: 1, minHeight: 0, overflow: "hidden" } : { flex: "1 0 auto" }),
      };

  return wrap(
    <AppShell current={openRun !== null ? "logs" : nav} onNavigate={(n) => { setOpenRun(null); setNav(n); }} cardStyle={cardStyle}>
      {content}
    </AppShell>
  );
}

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