const APPS = {
  about: { title: 'About', path: 'about', w: 820, h: 600, C: AboutApp },
  projects: { title: 'Projects', path: 'projects', w: 940, h: 620, C: ProjectsApp },
  experience: { title: 'Experience', path: 'experience', w: 720, h: 620, C: ExperienceApp },
  skills: { title: 'Skills', path: 'skills', w: 880, h: 600, C: SkillsApp },
  resume: { title: 'Resume.pdf', path: 'resume.pdf', w: 760, h: 820, C: ResumeApp },
  contact: { title: 'Contact', path: 'contact', w: 600, h: 520, C: ContactApp },
  terminal: { title: 'Terminal', path: 'terminal', w: 640, h: 420, C: TerminalApp }
};
const DESK = ['about', 'projects', 'experience', 'skills', 'resume', 'contact', 'terminal'];
const DOCK = ['about', 'projects', 'experience', 'skills', 'contact', 'terminal', '|', 'resume'];

const TWEAK_DEFAULTS = {
  "accent": "#B8F25C",
  "wallpaper": "grid",
  "motion": "default",
  "boot": true
};

function useViewport() {
  const [vp, setVp] = React.useState({ w: innerWidth, h: innerHeight });
  React.useEffect(() => { const r = () => setVp({ w: innerWidth, h: innerHeight }); window.addEventListener('resize', r); return () => window.removeEventListener('resize', r); }, []);
  return vp;
}
const centerOf = el => { if (!el) return null; const r = el.getBoundingClientRect(); return { x: r.left + r.width / 2, y: r.top + r.height / 2 }; };

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  window.__spd = { calm: 1.45, default: 1, snappy: 0.65 }[t.motion] || 1;
  const vp = useViewport(), mobile = vp.w < 760;
  const [phase, setPhase] = React.useState(t.boot ? 'boot' : 'live');
  const [live, setLive] = React.useState(!t.boot);
  const [wins, setWins] = React.useState([]);
  const [ctx, setCtx] = React.useState(null);
  const [sel, setSel] = React.useState(null);
  const [notif, setNotif] = React.useState(false);
  const z = React.useRef(10), dockRefs = React.useRef({}), deskRefs = React.useRef({});

  const open = (id, from, args) => {
    if (from && !(from instanceof Element)) { args = from; from = null; }
    const el = from || deskRefs.current[id] || dockRefs.current[id];
    const origin = centerOf(el);
    setWins(ws => {
      const nz = ++z.current, ex = ws.find(w => w.id === id);
      if (ex) return ws.map(w => w.id === id ? { ...w, z: nz, min: false, closing: false, args: args || w.args } : w);
      const a = APPS[id], n = ws.filter(w => !w.closing).length % 5;
      const W = Math.min(a.w, vp.w - 40), H = Math.min(a.h, vp.h - 40 - 104);
      const x = clamp(Math.round((vp.w - W) / 2 + (n - 2) * 30), 12, vp.w - W - 12);
      const y = clamp(Math.round((vp.h - 104 - H) / 2 + 20 + (n - 2) * 22), 38, Math.max(38, vp.h - 104 - H));
      return [...ws, { id, x, y, w: W, h: H, z: nz, min: false, max: false, origin, args }];
    });
    const d = dockRefs.current[id];
    if (d && !wins.find(w => w.id === id && !w.closing)) d.animate([{ transform: 'none' }, { transform: 'translateY(-22px)' }, { transform: 'none' }, { transform: 'translateY(-9px)' }, { transform: 'none' }], { duration: D(800), easing: 'ease-out' });
  };
  const upd = (id, p) => setWins(ws => ws.map(w => w.id === id ? { ...w, ...p } : w));
  const focus = id => { const top = wins.reduce((m, w) => Math.max(m, w.z), 0); const w = wins.find(x => x.id === id); if (w && w.z !== top) upd(id, { z: ++z.current }); };
  const close = id => upd(id, { closing: true });
  const gone = id => setWins(ws => ws.filter(w => w.id !== id));
  const os = { open, close };

  React.useEffect(() => {
    if (!live) return;
    const a = setTimeout(() => open('about', deskRefs.current.about), D(mobile ? 500 : 750));
    const b = setTimeout(() => setNotif(true), D(2600));
    return () => { clearTimeout(a); clearTimeout(b); };
  }, [live]);

  React.useEffect(() => {
    const k = e => {
      if (e.key === 'Escape' && !ctx && !e.target.closest('input,textarea')) {
        const vis = wins.filter(w => !w.min && !w.closing).sort((a, b) => b.z - a.z);
        if (vis[0]) close(vis[0].id);
      }
    };
    window.addEventListener('keydown', k); return () => window.removeEventListener('keydown', k);
  }, [wins, ctx]);

  const visible = wins.filter(w => !w.min && !w.closing);
  const topId = visible.length ? visible.reduce((a, b) => (a.z > b.z ? a : b)).id : null;
  const walls = ['grid', 'dots', 'plain'];
  const ctxItems = [
    { label: 'Open Terminal', hint: '>_', fn: () => open('terminal') },
    { label: 'Download CV', fn: () => { const a = document.createElement('a'); a.href = 'portfolio/resume.pdf'; a.download = 'Ata-Alp-Yildirim-CV.pdf'; a.click(); } },
    '-',
    { label: 'Change wallpaper', hint: t.wallpaper, fn: () => setTweak('wallpaper', walls[(walls.indexOf(t.wallpaper) + 1) % 3]) },
    { label: 'Minimize all', fn: () => setWins(ws => ws.map(w => ({ ...w, min: true }))) },
    '-',
    { label: 'Restart', hint: 'replay boot', fn: () => { setWins([]); setNotif(false); setLive(false); setPhase('boot'); } }
  ];

  return (
    <div className={'os' + (live ? ' live' : '') + (mobile ? ' mobile' : '')} style={{ '--acc': t.accent, '--spd': window.__spd }}
      onContextMenu={e => { if (e.target.closest('.win,input,textarea')) return; e.preventDefault(); setCtx({ x: e.clientX, y: e.clientY }); }}>
      <Wallpaper kind={t.wallpaper} />
      <div className="desk" onPointerDown={e => { if (e.target === e.currentTarget) setSel(null); }}>
        {!mobile && <NowWidget onOpen={open} />}
        <div className="dicons">
          {DESK.map((id, i) => (
            <button key={id} ref={el => deskRefs.current[id] = el} className={'dicon' + (sel === id ? ' sel' : '')} style={{ '--i': i }}
              onClick={e => { setSel(id); open(id, e.currentTarget); }}>
              <AppIcon id={id} size={mobile ? 48 : 52} />
              <span>{id === 'resume' ? 'Resume.pdf' : APPS[id].title}</span>
            </button>
          ))}
        </div>
      </div>
      {wins.map(w => {
        const a = APPS[w.id], C = a.C;
        return (
          <Win key={w.id} w={w} app={a} focused={w.id === topId} mobile={mobile} vp={vp}
            onFocus={() => focus(w.id)} onClose={() => close(w.id)} onGone={gone}
            onMin={() => upd(w.id, { min: true })} onMax={() => upd(w.id, { max: !w.max })}
            onRect={p => upd(w.id, p)} getDock={id => centerOf(dockRefs.current[id]) || { x: vp.w / 2, y: vp.h }}>
            <C os={os} args={w.args} />
          </Win>
        );
      })}
      <MenuBar focusedTitle={topId && APPS[topId].title} onOpen={open} onCtx={e => { const r = e.currentTarget.getBoundingClientRect(); setCtx({ x: r.left, y: r.bottom + 6 }); }} />
      <Dock items={DOCK.map(id => id === '|' ? '|' : { id, title: APPS[id].title })} running={wins.filter(w => !w.closing).map(w => w.id)} onOpen={open} refs={dockRefs} mobile={mobile} />
      {notif && !mobile && <Notif onView={() => open('projects', { sel: 'vizeradar' })} />}
      {ctx && <Ctx at={ctx} items={ctxItems} onClose={() => setCtx(null)} />}
      {phase === 'boot' && <Boot onReveal={() => setLive(true)} onDone={() => setPhase('live')} />}
    </div>
  );
}

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