// bdk-main.jsx — KevOS shell: boot → desktop (windows, icons, popups, taskbar) or mobile hub.

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "yeet",
  "scanlines": false,
  "chaos": 3,
  "live": true,
  "sound": true
}/*EDITMODE-END*/;

const BDK_DEFS = [
  { id: 'cta', title: 'Onboarding', glyph: '◆', w: 460, hot: true, app: 'cta' },
  { id: 'leader', title: 'Leaderboard', glyph: '▲', w: 400, app: 'leader' },
  { id: 'tiers', title: 'Rewards', glyph: '◇', w: 340, app: 'tiers' },
  { id: 'bounty', title: 'Bounty Board', glyph: '$', w: 340, app: 'bounty' },
  { id: 'tiermatch', title: 'Tier Match', glyph: '⇄', w: 380, app: 'tiermatch' },
  { id: 'slots', title: 'Kev Slots', glyph: '7', w: 320, app: 'slots' },
  { id: 'free', title: 'Free Money', glyph: '!', w: 360, app: 'free' },
];
const BDK_OPEN_DEFAULT = ['leader', 'cta', 'tiermatch', 'bounty', 'tiers'];
const BDK_ICON_IDS = ['cta', 'leader', 'tiers', 'bounty', 'tiermatch', 'slots', 'free'];
const BDK_TICKER_TEXT = 'BI-WEEKLY $3,000 WAGER RACE ◆ USE CODE BDKev ON YEET ◆ VIP TIER MATCH — BRING YOUR STATUS TO YEET ◆ 10 REWARD TIERS, BRONZE → ETERNAL ◆ SLOT BOUNTIES LIVE ◆ KEV IS NOT A FINANCIAL ADVISOR ◆ 18+ — PLAY RESPONSIBLY ◆ ';

// Windows live on a FIXED design canvas (design px) and the whole stage is
// scaled to fit any viewport — so the composition is identical at every
// resolution and never overlaps. Drag/resize deltas are divided by the scale.
const BDK_DESIGN_W = 1840;
const BDK_DESIGN_H = 1000;
const BDK_TOPBAR = 64;     // top menu bar height
const BDK_DOCKRES = 120;   // reserved space at the bottom for the dock
function bdkLayout() {
  const W = BDK_DESIGN_W;
  const cx = W / 2;
  return {
    cta:       { x: 0,         y: 0 },     // Onboarding — top-left (h~268)
    tiers:     { x: 0,         y: 290 },   // Rewards — under Onboarding (h~378)
    bounty:    { x: 0,         y: 690 },   // Bounty Board — bottom-left
    tiermatch: { x: 360,       y: 290 },   // Tier Match — right of Rewards
    leader:    { x: W - 404,   y: 210 },   // Leaderboard — top-right (clear above the Chairman mascot)
    slots:     { x: Math.round(cx - 160), y: 200 },
    free:      { x: Math.round(cx - 180), y: 260 },
  };
}
function bdkScale(vw, vh) {
  return Math.max(0.5, Math.min((vw - 40) / BDK_DESIGN_W, (vh - BDK_TOPBAR - BDK_DOCKRES) / BDK_DESIGN_H, 1.25));
}

function BdkApp() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [booted, setBooted] = React.useState(false);
  const [bootKey, setBootKey] = React.useState(0);
  const [wins, setWins] = React.useState(null);
  const [startOpen, setStartOpen] = React.useState(false);
  const [popups, setPopups] = React.useState([]);
  const [clock, setClock] = React.useState('');
  const [vw, setVw] = React.useState(window.innerWidth);
  const [vh, setVh] = React.useState(window.innerHeight);
  const zRef = React.useRef(60);
  const movedRef = React.useRef({});
  const firstPaint = React.useRef(true);
  const isMobile = vw < 880;
  const scale = bdkScale(vw, vh);

  window.BDKSOUND.enabled = !!t.sound;

  const initWins = React.useCallback(() => {
    const L = bdkLayout();
    const w = {};
    BDK_DEFS.forEach((d, i) => {
      w[d.id] = { ...L[d.id], z: 20 + i, open: BDK_OPEN_DEFAULT.includes(d.id), min: false };
    });
    w.cta.z = 45;
    setWins(w);
  }, []);

  React.useEffect(() => { initWins(); }, [initWins]);

  // positions are fixed design-space coords; on resize we only update the
  // viewport size so the stage scale recomputes (no per-window reflow needed).
  React.useEffect(() => {
    const onR = () => { setVw(window.innerWidth); setVh(window.innerHeight); };
    window.addEventListener('resize', onR);
    return () => window.removeEventListener('resize', onR);
  }, []);

  React.useEffect(() => {
    const tick = () => setClock(new Date().toLocaleTimeString('en-US', { hour12: false }));
    tick();
    const iv = setInterval(tick, 1000);
    return () => clearInterval(iv);
  }, []);

  React.useEffect(() => {
    if (booted) {
      const tm = setTimeout(() => { firstPaint.current = false; }, 1800);
      return () => clearTimeout(tm);
    }
  }, [booted]);

  // ── window manager ──
  const focusWin = (id) => setWins((w) => ({ ...w, [id]: { ...w[id], z: ++zRef.current } }));
  const moveWin = (id, x, y) => {
    movedRef.current[id] = true;
    setWins((w) => {
      const d = BDK_DEFS.find((dd) => dd.id === id);
      return {
        ...w,
        [id]: {
          ...w[id],
          x: Math.min(Math.max(x, -d.w + 130), BDK_DESIGN_W - 130),
          y: Math.min(Math.max(y, 0), BDK_DESIGN_H - 80),
        },
      };
    });
  };
  const resizeWin = (id, w, h) => {
    movedRef.current[id] = true;
    setWins((wn) => ({ ...wn, [id]: { ...wn[id], w: Math.max(260, Math.round(w)), h: Math.max(170, Math.round(h)) } }));
  };
  const closeWin = (id) => setWins((w) => ({ ...w, [id]: { ...w[id], open: false } }));
  const minWin = (id) => setWins((w) => ({ ...w, [id]: { ...w[id], min: true } }));
  const openWin = (id) => setWins((w) => ({ ...w, [id]: { ...w[id], open: true, min: false, z: ++zRef.current } }));
  const taskWin = (id) => setWins((w) => {
    const s = w[id];
    if (!s.open || s.min) return { ...w, [id]: { ...s, open: true, min: false, z: ++zRef.current } };
    return { ...w, [id]: { ...s, min: true } };
  });

  // ── popups ──
  const spawnPopup = React.useCallback((depth = 0, specIdx = null) => {
    setPopups((ps) => {
      if (ps.length >= 1) return ps;  // one at a time — no pile-ups
      const spec = BDK_POPUPS[specIdx == null ? Math.floor(Math.random() * 5) : specIdx];
      window.BDKSOUND.play('error');
      const vw = window.innerWidth, vh = window.innerHeight;
      return [...ps, {
        id: Math.random().toString(36).slice(2),
        // full-viewport position, biased toward the center so it reads as an alert
        x: Math.round(60 + Math.random() * Math.max(60, vw - 460)),
        y: Math.round(vh * 0.36 + Math.random() * Math.max(50, vh * 0.34)),
        spec, depth,
      }];
    });
  }, []);
  const closePopup = (id) => setPopups((ps) => ps.filter((p) => p.id !== id));
  const retryPopup = (p) => {
    if (p.depth < 2) setTimeout(() => spawnPopup(p.depth + 1, BDK_POPUPS.indexOf(p.spec)), 350);
  };

  React.useEffect(() => {
    if (!booted || !t.chaos) return;
    let alive = true;
    let timer;
    const loop = (delay) => {
      timer = setTimeout(() => {
        if (!alive) return;
        spawnPopup();
        loop((20000 + Math.random() * 25000) * (3 / t.chaos));
      }, delay);
    };
    loop(9000 * (3 / Math.max(t.chaos, 0.5)));
    return () => { alive = false; clearTimeout(timer); };
  }, [booted, t.chaos, spawnPopup]);

  const menuAction = (m) => {
    if (m === 'FILE') spawnPopup(0, 1);
    else if (m === 'EDIT') spawnPopup(0, 2);
    else if (m === 'VIEW') setTweak('scanlines', !t.scanlines);
    else if (m === 'GAMBLE') openWin('slots');
    else if (m === 'HELP') spawnPopup(0, 5);
  };

  const reboot = () => {
    setStartOpen(false);
    setPopups([]);
    movedRef.current = {};
    initWins();
    firstPaint.current = true;
    setBootKey((k) => k + 1);
    setBooted(false);
  };

  const APPS = {
    cta: () => <CtaApp></CtaApp>,
    leader: () => <LeaderApp></LeaderApp>,
    tiers: () => <TiersApp></TiersApp>,
    bounty: () => <ChallengeApp></ChallengeApp>,
    tiermatch: () => <TierMatchApp></TierMatchApp>,
    slots: () => <SlotsApp></SlotsApp>,
    free: () => <FreeMoneyApp></FreeMoneyApp>,
  };

  const openDelay = (id) => {
    if (!firstPaint.current) return 0;
    const i = BDK_OPEN_DEFAULT.indexOf(id);
    return i < 0 ? 0 : 220 + i * 110;
  };

  // THE site background — one value, same for everyone. Swap to any /backgrounds/bg-NN.png (still) or bg-NN.mp4 (animated).
  const BDK_BG = '/backgrounds/graffiti-paint.mp4';
  const wallVid = BDK_BG.slice(-4) === '.mp4' ? BDK_BG : '';
  const wallImg = wallVid ? '' : BDK_BG;
  return (
    <div className={'bdkroot theme-' + t.theme}>
      <div className="bdk-wall" aria-hidden="true" style={{ backgroundImage: wallVid ? 'none' : 'url(' + wallImg + ')' }}>
        {wallVid ? <video className="bdk-wall-vid" src={wallVid} autoPlay muted loop playsInline></video> : null}
      </div>
      {booted && !isMobile && wins && (
        <div data-screen-label="KevOS Desktop">
          <BdkMenubar onItem={menuAction} sound={!!t.sound} onSound={(v) => setTweak('sound', v)} live={!!t.live} clock={clock}></BdkMenubar>
          <div className="bdk-stage" style={{ width: BDK_DESIGN_W, height: BDK_DESIGN_H, left: '50%', top: BDK_TOPBAR + 6, transform: 'translateX(-50%) scale(' + scale + ')' }}>
            {BDK_DEFS.filter((d) => wins[d.id].open && !wins[d.id].min).map((d) => (
              <BdkWindow
                key={d.id}
                def={d}
                st={wins[d.id]}
                delay={openDelay(d.id)}
                scale={scale}
                onFocus={focusWin}
                onMove={moveWin}
                onResize={resizeWin}
                onClose={closeWin}
                onMin={minWin}
              >{APPS[d.app]()}</BdkWindow>
            ))}
          </div>
          {popups.map((p) => (
            <BdkPopup key={p.id} p={p} onClose={closePopup} onRetry={retryPopup}></BdkPopup>
          ))}
        </div>
      )}
      {booted && isMobile && (
        <BdkPhone
          t={t}
          APPS={APPS}
          clock={clock}
          live={!!t.live}
          sound={!!t.sound}
          onSound={(v) => setTweak('sound', v)}
          popups={popups}
          closePopup={closePopup}
          retryPopup={retryPopup}
        ></BdkPhone>
      )}
      {booted && !isMobile && <BdkMascot></BdkMascot>}
      {booted && !isMobile && (
        <BdkDock defs={BDK_DEFS} wins={wins} onOpen={openWin}></BdkDock>
      )}
      {!booted && <BootSequence key={bootKey} onDone={() => setBooted(true)}></BootSequence>}
      {t.scanlines && <div className="bdk-scanlines"></div>}
      <TweaksPanel>
        <TweakSection label="Mood"></TweakSection>
        <TweakRadio label="Theme" value={t.theme} options={['yeet', 'gold', 'neon', 'crt']} onChange={(v) => setTweak('theme', v)}></TweakRadio>
        <TweakToggle label="CRT scanlines" value={!!t.scanlines} onChange={(v) => setTweak('scanlines', v)}></TweakToggle>
        <TweakSection label="Chaos"></TweakSection>
        <TweakSlider label="Popup chaos" value={t.chaos} min={0} max={10} onChange={(v) => setTweak('chaos', v)}></TweakSlider>
        <TweakToggle label="Kev is live" value={!!t.live} onChange={(v) => setTweak('live', v)}></TweakToggle>
        <TweakToggle label="Sound" value={!!t.sound} onChange={(v) => setTweak('sound', v)}></TweakToggle>
        <TweakSection label="System"></TweakSection>
        <TweakButton label="Reboot KevOS" onClick={reboot}></TweakButton>
      </TweaksPanel>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<BdkApp></BdkApp>);
