/* ============ ATHARV.OS — Media Player with Spotify ============ */

/* ===== DOOM — js-dos runs in an ISOLATED same-origin iframe (doom.html) so
   the emulator's heavy WASM/worker code and any of its errors can never crash
   the portfolio. The 5MB shareware bundle loads only when this window opens. ===== */
function DoomContent() {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', flex: 1, minHeight: 0, background: '#000' }}>
      <iframe
        src="doom.html"
        title="DOOM (shareware, 1993)"
        style={{ flex: 1, minHeight: 0, width: '100%', border: 'none', background: '#000' }}
        allow="autoplay; fullscreen; gamepad"
        // Contain the emulator: no top-nav, no popups, no form posts. It needs
        // scripts + same-origin (to fetch the local bundle) + pointer-lock to play.
        sandbox="allow-scripts allow-same-origin allow-pointer-lock"
        referrerPolicy="no-referrer"
      />
      <div className="statusbar">
        <div className="scell flex">DOOM — id Software (1993 shareware)</div>
        <div className="scell">click the game · arrows + Ctrl</div>
      </div>
    </div>
  );
}

/* ===== Systems Status — live health of Atharv's deployed products (via /api/status) ===== */
function SystemsContent() {
  const [data, setData] = React.useState(null);
  const [state, setState] = React.useState('loading'); // loading | ok | error
  const load = React.useCallback(() => {
    setState(s => (s === 'ok' ? 'ok' : 'loading'));
    fetch('/api/status')
      .then(r => r.ok ? r.json() : Promise.reject())
      .then(j => { setData(j); setState('ok'); })
      .catch(() => setState('error'));
  }, []);
  React.useEffect(() => { load(); const iv = setInterval(load, 60000); return () => clearInterval(iv); }, [load]);

  const light = (up) => (
    <span style={{ display:'inline-block', width:12, height:12, borderRadius:'50%',
      background: up ? '#2ecc40' : '#ff4136', boxShadow: `0 0 6px ${up?'#2ecc40':'#ff4136'}`,
      border:'1px solid rgba(0,0,0,0.4)' }}/>
  );
  const services = (data && data.services) || [];
  const allUp = services.length && services.every(s => s.up);

  return (
    <div className="wbody white" style={{ padding:0, display:'flex', flexDirection:'column' }}>
      <div style={{ padding:'10px 12px', borderBottom:'1px solid #ccc', display:'flex', alignItems:'center', gap:10, background:'#f4f4f4' }}>
        <span style={{ fontSize:18 }}>{allUp ? '🟢' : services.length ? '🟠' : '⏳'}</span>
        <div style={{ flex:1 }}>
          <div style={{ fontWeight:700, fontSize:13 }}>Systems Status</div>
          <div style={{ fontSize:10, color:'#606060' }}>
            {state==='loading' && !data ? 'checking…' : allUp ? 'All systems operational' : services.length ? 'Some services degraded' : ''}
          </div>
        </div>
        <button className="btn" onClick={load} disabled={state==='loading'}>↻ Refresh</button>
      </div>
      <div style={{ flex:1, overflow:'auto', padding:'6px 0' }}>
        {state==='error' && !data && <div style={{ padding:16, fontSize:12, color:'#804000' }}>⚠ Couldn't reach the status service.</div>}
        {services.map((s, i) => (
          <div key={i} style={{ display:'flex', alignItems:'center', gap:10, padding:'8px 14px', borderBottom:'1px solid #eee' }}>
            {light(s.up)}
            <div style={{ flex:1, minWidth:0 }}>
              <div style={{ fontSize:12, fontWeight:700 }}>{s.name}</div>
              <a href={s.url} target="_blank" rel="noreferrer" style={{ fontSize:10, color:'#0000AA' }}>{s.url.replace(/^https?:\/\//,'').replace(/\/$/,'')}</a>
            </div>
            <div style={{ textAlign:'right', fontFamily:'Fixedsys, monospace', fontSize:11 }}>
              <div style={{ color: s.up ? '#1a7a1a' : '#b00' }}>{s.up ? 'UP' : (s.error || 'DOWN')}</div>
              <div style={{ color:'#808080' }}>{s.status ? `HTTP ${s.status}` : ''} {typeof s.ms==='number' ? `· ${s.ms}ms` : ''}</div>
            </div>
          </div>
        ))}
      </div>
      <div className="statusbar">
        <div className="scell flex">{data ? `Last checked ${new Date(data.checkedAt).toLocaleTimeString()}` : 'Live health monitor'}</div>
        <div className="scell">auto-refresh 60s</div>
      </div>
    </div>
  );
}

/* Pixel-art transport glyphs (12x12) */
const TP_GLYPHS = {
  prev: `<svg viewBox="0 0 12 12" width="12" height="12" shape-rendering="crispEdges"><rect x="1" y="2" width="1" height="8" fill="#000"/><rect x="2" y="2" width="1" height="8" fill="#000"/><polygon points="3,6 7,2 7,10" fill="#000"/><polygon points="7,6 11,2 11,10" fill="#000"/></svg>`,
  play: `<svg viewBox="0 0 12 12" width="12" height="12" shape-rendering="crispEdges"><polygon points="3,1 3,11 11,6" fill="#000"/></svg>`,
  pause: `<svg viewBox="0 0 12 12" width="12" height="12" shape-rendering="crispEdges"><rect x="3" y="2" width="2" height="8" fill="#000"/><rect x="7" y="2" width="2" height="8" fill="#000"/></svg>`,
  stop: `<svg viewBox="0 0 12 12" width="12" height="12" shape-rendering="crispEdges"><rect x="2" y="2" width="8" height="8" fill="#000"/></svg>`,
  next: `<svg viewBox="0 0 12 12" width="12" height="12" shape-rendering="crispEdges"><polygon points="1,2 5,6 1,10" fill="#000"/><polygon points="5,2 9,6 5,10" fill="#000"/><rect x="9" y="2" width="1" height="8" fill="#000"/><rect x="10" y="2" width="1" height="8" fill="#000"/></svg>`,
};

function MediaPlayerContent({ playing, setPlaying, currentTrack, setCurrentTrack }) {
  const playlists = D.playlists;
  const [active, setActive] = React.useState(0);
  const [volume, setVolume] = React.useState(70);
  const [muted, setMuted] = React.useState(false);
  const [bars, setBars] = React.useState(Array(32).fill(8));
  const [eq, setEq] = React.useState([4,8,12,6,10]);
  const iframeRef = React.useRef(null);
  const controllerRef = React.useRef(null);

  // Load Spotify iFrame API once
  React.useEffect(() => {
    if (window.__spotifyIFrameApiLoading) return;
    window.__spotifyIFrameApiLoading = true;
    if (!document.getElementById('spotify-iframe-api')) {
      const s = document.createElement('script');
      s.id = 'spotify-iframe-api';
      s.src = 'https://open.spotify.com/embed/iframe-api/v1';
      s.async = true;
      document.body.appendChild(s);
    }
  }, []);

  // Initialize controller when iframe is ready
  React.useEffect(() => {
    let cancelled = false;
    const init = () => {
      if (cancelled || !iframeRef.current || !window.SpotifyIframeApi) return;
      window.SpotifyIframeApi.createController(
        iframeRef.current,
        { uri: `spotify:playlist:${playlists[active].spotifyId}` },
        (ctrl) => {
          if (cancelled) return;
          controllerRef.current = ctrl;
          ctrl.addListener('playback_update', (e) => {
            if (!e || !e.data) return;
            // e.data.isPaused: true when paused
            if (typeof e.data.isPaused === 'boolean') {
              setPlaying(!e.data.isPaused);
            }
          });
        }
      );
    };
    if (window.SpotifyIframeApi) {
      init();
    } else {
      window.onSpotifyIframeApiReady = (api) => {
        window.SpotifyIframeApi = api;
        init();
      };
    }
    return () => {
      cancelled = true;
      if (controllerRef.current && controllerRef.current.destroy) {
        try { controllerRef.current.destroy(); } catch (e) {}
        controllerRef.current = null;
      }
    };
  }, []);

  React.useEffect(() => {
    if (!playing) { setBars(Array(32).fill(4)); setEq([4,4,4,4,4]); return; }
    const id = setInterval(() => {
      setBars(prev => prev.map(() => 8 + Math.random() * 90));
      setEq([4,8,12,6,10].map(()=>4 + Math.random()*14));
    }, 110);
    return () => clearInterval(id);
  }, [playing]);

  const pl = playlists[active];

  const togglePlay = () => {
    const c = controllerRef.current;
    if (c) {
      // togglePlay handles play/pause + autostart
      c.togglePlay();
    } else {
      setPlaying(p => !p);
    }
    if (!currentTrack) setCurrentTrack({ playlist: pl.name, idx: active });
  };

  const selectPlaylist = (i) => {
    setActive(i);
    const c = controllerRef.current;
    if (c) {
      c.loadUri(`spotify:playlist:${playlists[i].spotifyId}`);
      c.play();
    } else {
      setPlaying(true);
    }
    setCurrentTrack({ playlist: playlists[i].name, idx: i });
  };

  return (
    <div className="mp-winamp" style={{display:'flex', flexDirection:'column', flex:1, minHeight:0, fontFamily:"'MS Sans Serif', Tahoma, sans-serif", fontSmooth:'never', WebkitFontSmoothing:'none'}}>
      <div className="menubar">
        <button><span className="u">F</span>ile</button>
        <button><span className="u">V</span>iew</button>
        <button><span className="u">P</span>lay</button>
        <button><span className="u">F</span>avorites</button>
        <button><span className="u">H</span>elp</button>
      </div>
      <div className="mp-body">
        <div className="mp-left">
          <div className="mp-lh">▶ Playlists</div>
          {playlists.map((p, i) => (
            <div key={p.id} className={`pl-item ${i===active ? 'active' : ''}`} onClick={()=>selectPlaylist(i)}>
              <span style={{display:'inline-block', width:14, height:14, background:p.color, border:'1px solid #000', flexShrink:0}}/>
              <span style={{overflow:'hidden', textOverflow:'ellipsis'}}>{p.name}</span>
            </div>
          ))}
          <div className="mp-lh" style={{borderTop:'1px solid #3a3a55'}}>♪ Now Playing</div>
          <div style={{padding:'10px 8px', display:'flex', alignItems:'flex-end', gap:3, height:30, justifyContent:'center'}}>
            {eq.map((h,i)=><div key={i} style={{width:5, height:h+'px', background:'#39D353', boxShadow:'inset 0 1px 0 #7FFF7F'}}/>)}
          </div>
        </div>
        <div className="mp-right">
          <div className={`viz ${playing?'':'disabled'}`}>
            {bars.map((h, i) => <div key={i} className="viz-bar" style={{height: h + 'px'}}/>)}
          </div>
          <div className="mp-embed">
            <div ref={iframeRef} style={{width:'100%', height:'100%'}}/>
          </div>
          <div className="transport">
            <button className="tp-btn" title="Previous" onClick={()=>selectPlaylist((active-1+playlists.length)%playlists.length)} dangerouslySetInnerHTML={{__html: TP_GLYPHS.prev}}/>
            <button className="tp-btn" title={playing?'Pause':'Play'} onClick={togglePlay} dangerouslySetInnerHTML={{__html: playing ? TP_GLYPHS.pause : TP_GLYPHS.play}}/>
            <button className="tp-btn" title="Stop" onClick={()=>{ const c=controllerRef.current; if(c) c.pause(); setPlaying(false); }} dangerouslySetInnerHTML={{__html: TP_GLYPHS.stop}}/>
            <button className="tp-btn" title="Next" onClick={()=>selectPlaylist((active+1)%playlists.length)} dangerouslySetInnerHTML={{__html: TP_GLYPHS.next}}/>
            <div className="marquee">
              <span className="marquee-text">♪  Now playing: {pl.name}  ·  curated by devarv  ·  built at 2,000m altitude  ·  ATHARV.OS</span>
            </div>
            <div className="vol">
              <span dangerouslySetInnerHTML={{__html: ICO.speaker(16, muted)}} onClick={()=>setMuted(m=>!m)} style={{cursor:'pointer'}}/>
              <input type="range" min="0" max="100" value={muted?0:volume} onChange={e=>{setVolume(+e.target.value); setMuted(false);}} className="w95-trackbar"/>
            </div>
          </div>
        </div>
      </div>
      <div className="statusbar">
        <div className="scell flex">{playing ? '▶ Playing' : '❙❙ Paused'} — {pl.name}</div>
        <div className="scell">Vol: {muted?0:volume}%</div>
        <div className="scell">Spotify Embed</div>
      </div>
    </div>
  );
}

/* ===== My Computer / File Explorer ===== */
function MyComputerContent({ openApp, openProject, iconOverrides = {}, folderIcons = {} }) {
  const [path, setPath] = React.useState('C:\\');
  const [view, setView] = React.useState('icons');

  const tree = {
    'C:\\': [
      { name: 'Projects', type: 'folder', target: 'C:\\Projects', folderKey: 'projects' },
      { name: 'Awards', type: 'folder', target: 'C:\\Awards', folderKey: 'awards' },
      { name: 'Photos', type: 'folder', target: 'C:\\Photos', folderKey: 'photos' },
      { name: 'Notes', type: 'folder', target: 'C:\\Notes', folderKey: 'notes' },
      { name: 'README.txt', type: 'file', icon: 'readme', action: () => openApp('readme') },
      { name: 'Resume.pdf', type: 'file', icon: 'pdf', action: () => openApp('resume') },
    ],
    'C:\\Projects': D.projects.map(p => ({
      name: p.name + '.exe', type: 'file',
      icon: iconOverrides[p.slug] || p.iconKey,
      color: p.themeColor,
      action: () => openProject(p.slug)
    })),
    'C:\\Awards': [{ name: 'Awards', type: 'folder', action: () => openApp('awards') }],
    'C:\\Photos': [{ name: 'Photos', type: 'folder', action: () => openApp('photos') }],
    'C:\\Notes': [{ name: 'Notes.txt', type: 'file', icon: 'notes', action: () => openApp('notepad') }],
  };
  const items = tree[path] || [];

  return (
    <div style={{display:'flex', flexDirection:'column', flex:1, minHeight:0}}>
      <div className="menubar">
        <button><span className="u">F</span>ile</button>
        <button><span className="u">E</span>dit</button>
        <button><span className="u">V</span>iew</button>
        <button><span className="u">H</span>elp</button>
      </div>
      <div className="tbtoolbar">
        <button className="tbbtn" disabled={path==='C:\\'} onClick={()=>setPath(p => {
          const up = p.split('\\').slice(0,-1).join('\\');
          return (!up || up === 'C:') ? 'C:\\' : up;
        })}>↑ Up</button>
        <div className="tbsep"/>
        <button className={`tbbtn ${view==='icons'?'active':''}`} onClick={()=>setView('icons')}>▦ Icons</button>
        <button className={`tbbtn ${view==='details'?'active':''}`} onClick={()=>setView('details')}>≡ Details</button>
        <div className="tbsep"/>
        <span style={{fontSize:11, alignSelf:'center'}}><b>Address:</b> {path}</span>
      </div>
      <div className="wbody white" style={{flex:1, padding:0}}>
        {view==='icons' ? (
          <div className="icogrid" style={{padding:12}}>
            {items.map((it,i) => (
              <div className="item" key={i} onDoubleClick={()=>{
                if (it.type==='folder' && it.target) setPath(it.target);
                else if (it.action) it.action();
                else if (it.target) setPath(it.target);
              }} onClick={()=>{
                if (it.type==='folder' && it.target) setPath(it.target);
                else if (it.action) it.action();
                else if (it.target) setPath(it.target);
              }}>
                <div className="ico" dangerouslySetInnerHTML={{__html:
                  it.type==='folder'
                    ? (it.folderKey && folderIcons[it.folderKey]
                        ? (ICO[folderIcons[it.folderKey]] ? ICO[folderIcons[it.folderKey]](32) : ICO.folder(32))
                        : ICO.folder(32))
                    : (ICO[it.icon] ? ICO[it.icon](32, it.color) : ICO.readme(32))
                }}/>
                <div className="lbl">{it.name}</div>
              </div>
            ))}
          </div>
        ) : (
          <table className="detailtable">
            <thead><tr><th>Name</th><th>Type</th><th>Size</th></tr></thead>
            <tbody>
              {items.map((it,i) => (
                <tr key={i} onDoubleClick={()=>{
                  if (it.type==='folder' && it.target) setPath(it.target);
                  else if (it.action) it.action();
                }}>
                  <td>📄 {it.name}</td>
                  <td>{it.type==='folder'?'File Folder':'Application'}</td>
                  <td>{Math.round(Math.random()*900+100)} KB</td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>
      <div className="statusbar">
        <div className="scell flex">{items.length} object(s)</div>
        <div className="scell">{path}</div>
      </div>
    </div>
  );
}

/* ===== README ===== */
function ReadmeContent() {
  return (
    <div className="notepad-body">
{`README.TXT — devarv's portfolio
=====================================

Hello, traveller.

This is ATHARV.OS — a portfolio dressed up as a 1995
operating system because the real one I grew up with
came on dusty hand-me-down PCs and 1.44MB floppies.

What is in here:
  - 3 solo-built live products + 14 more (My Computer)
  - Real awards: HackathonX 1st (2025), HACKAP 2nd (2024)
  - Live links to deployed systems
  - A Notepad with field notes from the mountains
  - A Media Player wired to my actual Spotify playlists
  - A Resume.pdf for the recruiter in a hurry

Easter eggs:
  - Try Win+R (Run dialog)
  - Look closely at the desktop. It tilts.
  - Drag a window. It lifts.
  - The mountains are real. So am I.

Contact:
  atharv5873@gmail.com
  github.com/Atharv5873

— Atharv (devarv), Manali, Himachal Pradesh
`}
    </div>
  );
}

/* ===== Recycle Bin ===== */
function RecycleBinContent() {
  React.useEffect(() => {
    if (window.sfx) window.sfx.recycle();
  }, []);
  return (
    <div className="wbody white">
      <div style={{padding:24, textAlign:'center', color:'#404040'}}>
        <div dangerouslySetInnerHTML={{__html: ICO.recycle(64)}} style={{display:'inline-block', marginBottom:12}}/>
        <h3 style={{fontSize:13, fontWeight:700, marginBottom:6}}>Recycle Bin is empty.</h3>
        <p style={{fontSize:11, lineHeight:1.5}}>
          (Things devarv tried that didn't work — they're all here, but the file system swallowed them.)<br/><br/>
          <i>Failed migrations, abandoned drafts, an n8n side project, a doomed attempt to learn Rust on a 7-hour bus ride to Kullu, and a YAML parser written in pure Bash.</i><br/><br/>
          They served their purpose. Onward.
        </p>
      </div>
    </div>
  );
}

/* ===== Terminal ===== */
function TerminalContent({ openApp, openProject, lineHistory, addLine, sudoMode }) {
  const inputRef = React.useRef();
  const bottomRef = React.useRef();
  const [val, setVal] = React.useState('');
  const [cmdHist, setCmdHist] = React.useState([]);
  const [histIdx, setHistIdx] = React.useState(-1);

  React.useEffect(() => {
    bottomRef.current?.scrollIntoView({behavior:'auto'});
    inputRef.current?.focus();
  }, [lineHistory]);

  const out = (text) => addLine({ type:'out', text });
  const err = (text) => addLine({ type:'err', text });

  // slug/name resolver for `open` and `cat`
  const projList = (D.projects || []);
  const findProj = (q) => projList.find(p => p.slug === q || p.name.toLowerCase() === q || p.name.toLowerCase().includes(q));
  const APP_ALIASES = { about:'about', me:'about', projects:'mycomputer', 'my computer':'mycomputer', mycomputer:'mycomputer',
    skills:'skills', experience:'experience', exp:'experience', awards:'awards', photos:'photos', notes:'notepad', notepad:'notepad',
    resume:'resume', cv:'resume', readme:'readme', network:'network', ie:'ie', browser:'ie', media:'mediaplayer', spotify:'mediaplayer',
    chat:'chat', ai:'chat', devarv:'chat', hiring:'hiring', hire:'hiring', solitaire:'solitaire', minesweeper:'minesweeper',
    mines:'minesweeper', doom:'doom', terminal:'terminal' };

  const run = (raw) => {
    const cmd = raw.trim();
    if (!cmd) return;
    addLine({ type:'cmd', text: cmd });
    setCmdHist(h => [...h, cmd]); setHistIdx(-1);
    const c = cmd.toLowerCase();
    const [verb, ...rest] = c.split(/\s+/);
    const arg = rest.join(' ');

    if (c==='help' || c==='?' || verb==='man') {
      out([
        'ATHARV.OS shell — available commands:',
        '  help              this list',
        '  whoami / id       who is logged in',
        '  ls [projects]     list files / projects',
        '  open <name>       open an app or project window   (e.g. `open hiring`, `open royalbankpacific`)',
        '  cat <file>        README.txt · resume · <project>',
        '  projects          summary of all projects',
        '  skills            top skills by category',
        '  experience        work history',
        '  status            live status of my deployed products',
        '  neofetch          system info',
        '  pwd · date · echo · uname -a · history · clear · exit',
        '  easter eggs:      sudo · make-coffee · matrix · konami · hire',
      ].join('\n'));
    }
    else if (c==='whoami' || c==='id') out(sudoMode ? 'root' : 'devarv — Atharv Sharma, Backend & AI Engineer');
    else if (verb==='ls' || verb==='dir') {
      if (arg.startsWith('project')) out(projList.map(p => p.slug).join('  '));
      else out('projects/  awards/  photos/  notes/  resume.pdf  README.txt  HIRING.TXT');
    }
    else if (verb==='open') {
      const p = findProj(arg);
      if (p && openProject) { out(`opening ${p.name} …`); openProject(p.slug); }
      else if (APP_ALIASES[arg]) { out(`opening ${arg} …`); openApp(APP_ALIASES[arg]); }
      else err(`open: '${arg||''}' not found — try \`ls projects\` or \`open hiring\``);
    }
    else if (verb==='cat') {
      if (arg==='readme.txt' || arg==='readme') { out('opening README.txt …'); openApp('readme'); }
      else if (arg==='resume' || arg==='resume.pdf' || arg==='cv') { out('opening Resume.pdf …'); openApp('resume'); }
      else { const p = findProj(arg); if (p) out(`${p.name} ${p.version||''}\n  ${p.tagline}\n  stack: ${p.stack.join(', ')}\n  ${p.headlineMetric||''}${p.live?'\n  live: '+p.live:''}${p.repo?'\n  repo: '+p.repo:''}`); else err(`cat: ${arg||''}: no such file`); }
    }
    else if (c==='projects') out(projList.map(p => `  ${p.name}${p.live?'  ['+p.live.replace(/^https?:\/\//,'').replace(/\/$/,'')+']':''}`).join('\n'));
    else if (c==='skills') out((D.skillCategories||[]).slice(0,4).map(cat => `  ${cat.name}: ${cat.skills.slice(0,4).map(s=>s.n).join(', ')}`).join('\n'));
    else if (c==='experience' || c==='exp') out((D.experience||[]).map(e => `  ${e.role} @ ${e.company} (${e.period})`).join('\n'));
    else if (c==='status' || c==='ping') { out('checking deployed products …'); openApp('systems'); }
    else if (c==='neofetch' || c==='screenfetch') out([
      "        .--.        devarv@atharv-os",
      "       |o_o |       ----------------",
      "       |:_/ |       OS:     ATHARV.OS 1.0 (2026)",
      "      //   \\ \\      Shell:  bash (in-browser)",
      "     (|     | )     Role:   Backend & AI Engineer",
      "    /'\\_   _/`\\     Stack:  Python · FastAPI · LangGraph",
      "    \\___)=(___/     Uptime: since 1995 🏔",
    ].join('\n'));
    else if (c==='pwd') out('/home/devarv');
    else if (verb==='echo') out(cmd.slice(5));
    else if (c==='date') out(new Date().toString());
    else if (c==='uname -a') out('ATHARV.OS 1.0 (build 2026.04) #1 SMP devarv-kernel x86_64 GNU/Mountain');
    else if (c==='history') out(cmdHist.map((h,i)=>`  ${i+1}  ${h}`).join('\n') || '  (empty)');
    else if (c==='sudo' || c==='sudo su') out('[sudo] devarv is not in the sudoers file. This incident will be reported. 😏 (try `make-coffee`)');
    else if (c==='make-coffee') out('☕ brewing… HTTP 418: I\'m a teapot. The mug is in another castle.');
    else if (c==='hire') out('contact:\n  email:    atharv5873@gmail.com\n  linkedin: linkedin.com/in/atharv-sharma-devarv\n  → run `open hiring` for the full pitch');
    else if (c==='matrix') { out('wake up, neo…'); window.dispatchEvent(new CustomEvent('atharv:matrix')); }
    else if (c==='konami') { out('↑↑↓↓←→←→BA — fireworks engaged.'); window.dispatchEvent(new CustomEvent('atharv:konami')); }
    else if (c==='clear' || c==='cls') window.dispatchEvent(new CustomEvent('atharv:clearterm'));
    else if (c==='exit' || c==='quit' || c==='logout') out('(close the window to exit, traveller)');
    else err(`bash: ${cmd.split(/\s+/)[0]}: command not found — type \`help\``);
    setVal('');
  };

  const handleSubmit = (e) => { e.preventDefault(); run(val); };
  const onKey = (e) => {
    if (e.key === 'ArrowUp') { e.preventDefault(); if (!cmdHist.length) return; const i = histIdx < 0 ? cmdHist.length-1 : Math.max(0, histIdx-1); setHistIdx(i); setVal(cmdHist[i]); }
    else if (e.key === 'ArrowDown') { e.preventDefault(); if (histIdx < 0) return; const i = histIdx+1; if (i >= cmdHist.length) { setHistIdx(-1); setVal(''); } else { setHistIdx(i); setVal(cmdHist[i]); } }
  };

  return (
    <div className="terminal" onClick={()=>inputRef.current?.focus()}>
      <div>ATHARV.OS [Version 1.0.2026]</div>
      <div>(c) 2026 devarv. All rights reserved. — type <b>help</b></div>
      <div style={{height:8}}/>
      {lineHistory.map((l, i) => {
        if (l.type==='cmd') return <div key={i}><span className="prompt">{sudoMode?'root':'devarv'}@atharv-os:~$</span> {l.text}</div>;
        if (l.type==='err') return <div key={i} style={{color:'#ff7777', whiteSpace:'pre-wrap'}}>{l.text}</div>;
        return <div key={i} style={{whiteSpace:'pre-wrap'}}>{l.text}</div>;
      })}
      <form onSubmit={handleSubmit}>
        <span className="prompt">{sudoMode?'root':'devarv'}@atharv-os:~$&nbsp;</span>
        <input ref={inputRef} value={val} onChange={e=>setVal(e.target.value)} onKeyDown={onKey} autoFocus/>
      </form>
      <div ref={bottomRef}/>
    </div>
  );
}

/* ===== Tip of the Day ===== */
function TipOfTheDay({ onClose }) {
  const tips = [
    "Drag any window — it lifts off the 3D plane in real time.",
    "Press Win+R to open the Run dialog. Try typing 'matrix'.",
    "Every project icon is real and shipped to production. Double-click to inspect.",
    "The mountains in Photos are not stock photos. They are placeholders for places I have actually been.",
    "Don't see a Tweaks panel? Toggle it from the toolbar — it's hiding above this OS.",
    "Older Hindi songs and `tail -f` on a production log. The two best soundtracks I know."
  ];
  const tip = tips[Math.floor(Date.now()/86400000) % tips.length];
  return (
    <div style={{display:'flex', flexDirection:'column', flex:1, minHeight:0}}>
      <div className="tip-of-the-day">
        <div className="icon">💡</div>
        <div className="text">
          <h3>Did you know...</h3>
          <p>{tip}</p>
        </div>
      </div>
      <div style={{padding:8, borderTop:'1px solid #fff', display:'flex', justifyContent:'flex-end', background:'#C0C0C0'}}>
        <button className="btn" onClick={onClose}>Close</button>
      </div>
    </div>
  );
}

Object.assign(window, {
  MediaPlayerContent, MyComputerContent, ReadmeContent,
  RecycleBinContent, TerminalContent, TipOfTheDay
});
