/* ============ ATHARV.OS — Shell (window manager, taskbar, desktop) ============ */

let _winId = 1;
const newWinId = () => 'w' + (_winId++);

/* ===== Boot Screen — phosphor-green BIOS POST =====
   Real POST pacing: bursts of lines, hard 300-700ms pauses (disk seeks),
   one 900ms hesitation, and a live memory count-up. Total ≤ 6s.
   Easter egg: pressing DEL during boot opens the Tweaks panel once the
   desktop loads (app.jsx checks window.__aosBootDel). */
function BootScreen({ onDone }) {
  const [lines, setLines] = React.useState([]);
  const [done, setDone] = React.useState(false);
  const reduced = React.useMemo(
    () => window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches,
    []
  );

  React.useEffect(() => {
    const onKey = (e) => { if (e.key === 'Delete') window.__aosBootDel = true; };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  React.useEffect(() => {
    // t = delay BEFORE the line appears; mem = live count-up line
    const seq = [
      { t: 60,  l: 'ATHARV.OS BIOS v1.0.2026 — devarv labs' },
      { t: 16,  l: 'Copyright (C) 2026 Atharv Sharma. All rights reserved.' },
      { t: 16,  l: '' },
      { t: 380, mem: true },
      { t: 90,  l: 'CPU: 4-core agentic processor (LangGraph enabled)' },
      { t: 480, l: 'Detecting drives...' },
      { t: 900, l: '   Primary IDE Master   : ATHARV-95 4.0GB         OK' },
      { t: 16,  l: '   Primary IDE Slave    : MOUNTAIN-PHOTOS 2.0GB   OK' },
      { t: 16,  l: '   Secondary IDE Master : SPOTIFY-CDROM           OK' },
      { t: 420, l: '' },
      { t: 16,  l: 'Loading kernel modules...' },
      { t: 16,  l: '   [OK]  systemd-mountain-monitor.service' },
      { t: 16,  l: '   [OK]  langgraph-orchestrator.service' },
      { t: 330, l: '   [OK]  fail2ban.service' },
      { t: 16,  l: '   [OK]  nginx-tls.service' },
      { t: 16,  l: '   [OK]  cron-self-healing.timer' },
      { t: 380, l: '' },
      { t: 16,  l: 'Mounting /home/devarv ...               OK' },
      { t: 60,  l: 'Loading desktop environment ...         OK' },
      { t: 280, l: '' },
      { t: 16,  l: 'Press DEL to enter SETUP' },
      { t: 700, l: 'Welcome to ATHARV.OS.' },
    ];
    let i = 0;
    let cancelled = false;
    const timers = [];
    const ivals = [];
    const later = (fn, ms) => { timers.push(setTimeout(fn, ms)); };
    const step = () => {
      if (cancelled) return;
      if (i >= seq.length) { later(() => setDone(true), 350); return; }
      const it = seq[i++];
      later(() => {
        if (cancelled) return;
        if (it.mem) {
          if (reduced) {
            // reduced motion: count-up is instant
            setLines(L => [...L, 'Memory test: 32768K OK']);
            step();
            return;
          }
          setLines(L => [...L, 'Memory test: 0K']);
          let k = 0;
          const iv = setInterval(() => {
            if (cancelled) { clearInterval(iv); return; }
            k = Math.min(32768, k + 640);
            const txt = k >= 32768 ? 'Memory test: 32768K OK' : `Memory test: ${k}K`;
            setLines(L => { const c = L.slice(); c[c.length - 1] = txt; return c; });
            if (k >= 32768) { clearInterval(iv); step(); }
          }, 10);
          ivals.push(iv);
        } else {
          setLines(L => [...L, it.l]);
          step();
        }
      }, reduced ? Math.min(it.t, 40) : it.t);
    };
    step();
    return () => {
      cancelled = true;
      timers.forEach(clearTimeout);
      ivals.forEach(clearInterval);
    };
  }, [reduced]);

  React.useEffect(() => {
    if (done) {
      const t = setTimeout(onDone, 700);
      return () => clearTimeout(t);
    }
  }, [done, onDone]);

  return (
    <div className="boot">
      {lines.join('\n')}
      <span className="cursor">{done ? '' : '▮'}</span>
      <button className="skip" onClick={onDone}>Skip ▶</button>
    </div>
  );
}

/* ===== Splash ===== */
function SplashScreen({ onDone }) {
  const [pct, setPct] = React.useState(0);
  const [loaded, setLoaded] = React.useState(false);
  React.useEffect(() => {
    const img = new Image();
    img.onload = () => setLoaded(true);
    img.src = 'assets/loading-splash.jpg';
  }, []);
  // (No startup sound — the splash used to trigger sfx.modem here, which
  //  became the full dial-up synth. Boot is silent by design now.)
  React.useEffect(() => {
    if (!loaded) return;
    const t = setTimeout(onDone, 3400);
    const iv = setInterval(() => {
      setPct(p => Math.min(100, p + 2 + Math.random() * 4));
    }, 90);
    return () => { clearTimeout(t); clearInterval(iv); };
  }, [loaded, onDone]);
  return (
    <div className="splash-img" style={{ background: '#3f86e0' }}>
      {loaded && (
        <>
          <div className="splash-photo"/>
          <div className="splash-bar">
            <div className="splash-fill" style={{ width: pct + '%' }}/>
          </div>
        </>
      )}
    </div>
  );
}

/* ===== Window component ===== */
function Window({ win, focused, onFocus, onClose, onMinimize, onMaximize, onUpdate, children, zIndex }) {
  const [drag, setDrag] = React.useState(null);
  const [size, setSize] = React.useState({ w: win.w, h: win.h });
  const [pos, setPos] = React.useState({ x: win.x, y: win.y });
  const [maxed, setMaxed] = React.useState(false);
  const [resizing, setResizing] = React.useState(null);
  const [roll, setRoll] = React.useState(-1);
  const winRef = React.useRef();
  const lastMove = React.useRef({ x: 0, t: 0 });

  React.useEffect(() => { setSize({ w: win.w, h: win.h }); }, [win.w, win.h]);
  React.useEffect(() => { setPos({ x: win.x, y: win.y }); }, [win.x, win.y]);

  // Drag handler
  React.useEffect(() => {
    if (!drag) return;
    const move = (e) => {
      const x = Math.max(-100, Math.min(window.innerWidth - 80, e.clientX - drag.dx));
      const y = Math.max(0, Math.min(window.innerHeight - 60, e.clientY - drag.dy));
      // Velocity → roll (spring-like)
      const now = performance.now();
      const dt = Math.max(1, now - lastMove.current.t);
      const vx = (e.clientX - lastMove.current.x) / dt;
      lastMove.current = { x: e.clientX, t: now };
      const targetRoll = Math.max(-6, Math.min(6, vx * 4));
      setRoll(r => r + (targetRoll - r) * 0.18);
      setPos({ x, y });
    };
    const up = () => {
      setDrag(null);
      // settle roll back
      let r = 0;
      const settle = setInterval(() => {
        setRoll(prev => {
          const nx = prev + (-1 - prev) * 0.22;
          if (Math.abs(nx - (-1)) < 0.05) { clearInterval(settle); return -1; }
          return nx;
        });
      }, 16);
      onUpdate(win.id, { x: pos.x, y: pos.y });
    };
    window.addEventListener('mousemove', move);
    window.addEventListener('mouseup', up);
    return () => {
      window.removeEventListener('mousemove', move);
      window.removeEventListener('mouseup', up);
    };
  }, [drag, pos.x, pos.y]);

  // Resize handler
  React.useEffect(() => {
    if (!resizing) return;
    const move = (e) => {
      const dx = e.clientX - resizing.sx;
      const dy = e.clientY - resizing.sy;
      setSize({
        w: Math.max(280, resizing.w0 + dx),
        h: Math.max(160, resizing.h0 + dy),
      });
    };
    const up = () => setResizing(null);
    window.addEventListener('mousemove', move);
    window.addEventListener('mouseup', up);
    return () => {
      window.removeEventListener('mousemove', move);
      window.removeEventListener('mouseup', up);
    };
  }, [resizing]);

  const startDrag = (e) => {
    if (maxed) return;
    if (window.matchMedia && window.matchMedia('(max-width: 900px)').matches) {
      onFocus(win.id);
      return;
    }
    onFocus(win.id);
    const r = winRef.current.getBoundingClientRect();
    setDrag({ dx: e.clientX - r.left, dy: e.clientY - r.top });
  };

  const toggleMax = () => {
    // micro channel-flip on maximize/restore (half intensity)
    if (window.AOS_FX && window.AOS_FX.channelFlip) window.AOS_FX.channelFlip(0.5);
    if (maxed) {
      setMaxed(false);
    } else {
      setMaxed(true);
    }
  };

  const styleObj = maxed ? {
    // small inset: keeps the titlebar controls (✕ etc.) clear of the tube's
    // rounded corners — #tv-screen clips (and un-hit-tests) outside the arc
    left: 3, top: 3, width: 'calc(100% - 6px)', height: 'calc(100% - 32px)',
    zIndex,
    '--drag-roll': `${roll}deg`,
  } : {
    left: pos.x, top: pos.y, width: size.w, height: size.h, zIndex,
    '--drag-roll': `${roll}deg`,
  };

  return (
    <div
      ref={winRef}
      className={`win ${maxed?'maxed':''} ${focused?'focused':''} ${drag?'dragging':''} ${win.opening?'opening':''} ${win.minimizing?'minimizing':''} ${win.closing?'closing':''}`}
      style={styleObj}
      onMouseDown={()=>onFocus(win.id)}
    >
      <div
        className={`tbar ${drag?'dragging':''}`}
        onMouseDown={startDrag}
        onDoubleClick={toggleMax}
      >
        <span className="ico" dangerouslySetInnerHTML={{__html: ICO[win.iconKey] ? ICO[win.iconKey](16, win.iconColor) : ICO.myComputer(16)}}/>
        <span className="ttl">{win.title}</span>
        <div className="tctrls">
          <button className="tctrl" title="Minimize" aria-label={`Minimize ${win.title}`} onClick={(e)=>{e.stopPropagation(); if (window.sfx) window.sfx.minimize(); onMinimize(win.id);}}>_</button>
          <button className="tctrl" title="Maximize" aria-label={`${maxed?'Restore':'Maximize'} ${win.title}`} onClick={(e)=>{e.stopPropagation(); if (window.sfx) window.sfx.maximize(); toggleMax();}}>{maxed?'❐':'□'}</button>
          <button className="tctrl" title="Close" aria-label={`Close ${win.title}`} onClick={(e)=>{e.stopPropagation(); if (window.sfx) window.sfx.click(); onClose(win.id);}}>✕</button>
        </div>
      </div>
      {children}
      {!maxed && (
        <div
          className="win-resize"
          style={{
            position:'absolute', right:0, bottom:0, width:14, height:14,
            cursor:'nwse-resize',
            background: 'linear-gradient(135deg, transparent 50%, #808080 50%, #808080 60%, transparent 60%, transparent 70%, #808080 70%, #808080 80%, transparent 80%)'
          }}
          onMouseDown={(e)=>{
            if (window.matchMedia && window.matchMedia('(max-width: 900px)').matches) return;
            setResizing({ sx: e.clientX, sy: e.clientY, w0: size.w, h0: size.h });
            onFocus(win.id);
            e.stopPropagation();
          }}
        />
      )}
    </div>
  );
}

/* ===== Start Menu ===== */
function StartMenu({ onSelect, onClose }) {
  React.useEffect(() => {
    const handler = (e) => {
      if (!e.target.closest('.startmenu') && !e.target.closest('.startbtn')) onClose();
    };
    setTimeout(() => document.addEventListener('mousedown', handler), 0);
    return () => document.removeEventListener('mousedown', handler);
  }, [onClose]);

  return (
    <div className="startmenu" onClick={(e)=>e.stopPropagation()}>
      <div className="strip"><span>Atharv OS</span></div>
      <div className="items">
        <div className="smitem" onClick={()=>onSelect('about')}>
          <div className="ico" dangerouslySetInnerHTML={{__html: ICO.about(24)}}/>
          <span><b>About me</b></span>
        </div>
        <div className="smitem">
          <div className="ico" dangerouslySetInnerHTML={{__html: ICO.folder(24)}}/>
          <span>Programs</span>
          <span className="arrow">▶</span>
          <div className="submenu">
            <div className="smitem" onClick={()=>onSelect('chat')}>
              <div className="ico" dangerouslySetInnerHTML={{__html: ICO.chat(24)}}/>
              <span>devarv.ai</span>
            </div>
            <div className="smitem" onClick={()=>onSelect('mediaplayer')}>
              <div className="ico" dangerouslySetInnerHTML={{__html: ICO.mediaPlayer(24)}}/>
              <span>Media Player</span>
            </div>
            <div className="smitem" onClick={()=>onSelect('terminal')}>
              <div className="ico" dangerouslySetInnerHTML={{__html: ICO.terminal(24)}}/>
              <span>MS-DOS Prompt</span>
            </div>
            <div className="smitem">
              <div className="ico" dangerouslySetInnerHTML={{__html: ICO.folder(24)}}/>
              <span>Games</span>
              <span className="arrow">▶</span>
              <div className="submenu">
                <div className="smitem" onClick={()=>onSelect('solitaire')}>
                  <div className="ico" dangerouslySetInnerHTML={{__html: ICO.solitaire(24)}}/>
                  <span>Solitaire</span>
                </div>
                <div className="smitem" onClick={()=>onSelect('minesweeper')}>
                  <div className="ico" dangerouslySetInnerHTML={{__html: ICO.mines(24)}}/>
                  <span>Minesweeper</span>
                </div>
                <div className="smitem" onClick={()=>onSelect('doom')}>
                  <div className="ico" dangerouslySetInnerHTML={{__html: ICO.doom(24)}}/>
                  <span>DOOM</span>
                </div>
              </div>
            </div>
            <div className="smitem" onClick={()=>onSelect('notepad')}>
              <div className="ico" dangerouslySetInnerHTML={{__html: ICO.notes(24)}}/>
              <span>Notepad</span>
            </div>
            <div className="smitem" onClick={()=>onSelect('photos')}>
              <div className="ico" dangerouslySetInnerHTML={{__html: ICO.photos(24)}}/>
              <span>Photo Viewer</span>
            </div>
            <div className="smitem" onClick={()=>onSelect('screensaver')}>
              <div className="ico" dangerouslySetInnerHTML={{__html: ICO.terminal(24)}}/>
              <span>Screensaver</span>
            </div>
          </div>
        </div>
        <div className="smitem">
          <div className="ico" dangerouslySetInnerHTML={{__html: ICO.folder(24)}}/>
          <span>Documents</span>
          <span className="arrow">▶</span>
          <div className="submenu">
            <div className="smitem" onClick={()=>onSelect('hiring')}>
              <div className="ico" dangerouslySetInnerHTML={{__html: ICO.briefcase(24)}}/>
              <span>HIRING.TXT</span>
            </div>
            <div className="smitem" onClick={()=>onSelect('readme')}>
              <div className="ico" dangerouslySetInnerHTML={{__html: ICO.readme(24)}}/>
              <span>README.txt</span>
            </div>
            <div className="smitem" onClick={()=>onSelect('resume')}>
              <div className="ico" dangerouslySetInnerHTML={{__html: ICO.pdf(24)}}/>
              <span>Resume.pdf</span>
            </div>
            <div className="smitem" onClick={()=>onSelect('notepad')}>
              <div className="ico" dangerouslySetInnerHTML={{__html: ICO.notes(24)}}/>
              <span>Notes.txt</span>
            </div>
          </div>
        </div>
        <div className="smitem">
          <div className="ico" dangerouslySetInnerHTML={{__html: ICO.skillsCpl(24)}}/>
          <span>Settings</span>
          <span className="arrow">▶</span>
          <div className="submenu">
            <div className="smitem" onClick={()=>onSelect('systems')}>
              <div className="ico" dangerouslySetInnerHTML={{__html: ICO.systems(24)}}/>
              <span>Systems Status</span>
            </div>
            <div className="smitem" onClick={()=>onSelect('skills')}>
              <div className="ico" dangerouslySetInnerHTML={{__html: ICO.skillsCpl(24)}}/>
              <span>Skills (Control Panel)</span>
            </div>
            <div className="smitem" onClick={()=>onSelect('experience')}>
              <div className="ico" dangerouslySetInnerHTML={{__html: ICO.experience(24)}}/>
              <span>Experience.log</span>
            </div>
            <div className="smitem" onClick={()=>onSelect('awards')}>
              <div className="ico" dangerouslySetInnerHTML={{__html: ICO.awards(24)}}/>
              <span>Awards</span>
            </div>
          </div>
        </div>
        <div className="smitem" onClick={()=>onSelect('mycomputer')}>
          <div className="ico" dangerouslySetInnerHTML={{__html: ICO.myComputer(24)}}/>
          <span>My Computer</span>
        </div>
        <div className="smitem" onClick={()=>onSelect('network')}>
          <div className="ico" dangerouslySetInnerHTML={{__html: ICO.network(24)}}/>
          <span>Network Neighborhood</span>
        </div>
        <div className="smitem" onClick={()=>onSelect('run')}>
          <div className="ico" style={{fontSize:18}}>🏃</div>
          <span><span style={{textDecoration:'underline'}}>R</span>un...</span>
        </div>
        <div className="smitem divider"/>
        <div className="smitem" onClick={()=>onSelect('shutdown')}>
          <div className="ico" style={{fontSize:18}}>⏻</div>
          <span><b>Sh<span style={{textDecoration:'underline'}}>u</span>t Down...</b></span>
        </div>
      </div>
    </div>
  );
}

/* ===== Clock ===== */
function Clock() {
  const [now, setNow] = React.useState(new Date());
  React.useEffect(() => {
    const id = setInterval(() => setNow(new Date()), 1000);
    return () => clearInterval(id);
  }, []);
  const h = now.getHours(); const m = now.getMinutes();
  const ampm = h >= 12 ? 'PM' : 'AM';
  const h12 = ((h + 11) % 12) + 1;
  return (
    <span className="clock" title={now.toString()}>
      {String(h12).padStart(2,'0')}<span className="blink">:</span>{String(m).padStart(2,'0')} {ampm}
    </span>
  );
}

/* ===== Now Playing widget ===== */
function NowPlayingWidget({ playing, currentTrack, onOpen, onToggle }) {
  const [bars, setBars] = React.useState([4,8,12,6]);
  React.useEffect(() => {
    if (!playing) { setBars([4,4,4,4]); return; }
    const id = setInterval(() => setBars([4,8,12,6].map(()=>4 + Math.random()*10)), 180);
    return () => clearInterval(id);
  }, [playing]);
  if (!currentTrack) return null;
  return (
    <div className="np-widget win raised">
      <div className="tbar focused" style={{cursor:'default'}}>
        <span className="ttl">♪ Now Playing</span>
        <div className="tctrls">
          <button className="tctrl" onClick={onOpen} title="Open Player">↗</button>
        </div>
      </div>
      <div className="np-content">
        <div className="np-row">
          <div className="np-eq">
            {bars.map((h,i)=><div key={i} className="np-eq-bar" style={{height: h+'px'}}/>)}
          </div>
          <div style={{flex:1, minWidth:0}}>
            <div className="np-track">{currentTrack.playlist}</div>
            <div className="np-pl">via Spotify · ATHARV.OS</div>
          </div>
          <button className="tp-btn" onClick={onToggle} style={{height:22}}>{playing?'❙❙':'▶'}</button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, {
  newWinId, BootScreen, SplashScreen, Window, StartMenu, Clock, NowPlayingWidget
});
