/* win95-core.jsx — window manager primitives for Cip's Desktop
   Exports to window at the bottom. */

const { useState, useEffect, useRef, useCallback } = React;

const ICON = (name) => `assets/icons/${name}.png`;

/* ---------------- Button ---------------- */
function W95Button({ children, small, def, pressed, style, ...rest }) {
  return (
    <button
      className={'w95-btn' + (small ? ' w95-btn--sm' : '') + (def ? ' w95-btn--default' : '') + (pressed ? ' w95-btn--pressed' : '')}
      style={style}
      {...rest}
    >{children}</button>
  );
}

/* ---------------- Menu bar with dropdowns ---------------- */
/* menus: [{label, items: [{label, icon, onClick, disabled, sep}]}] */
function MenuBar({ menus }) {
  const [open, setOpen] = useState(null);
  const ref = useRef(null);
  useEffect(() => {
    const close = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(null); };
    document.addEventListener('mousedown', close);
    return () => document.removeEventListener('mousedown', close);
  }, []);
  return (
    <ul className="w95-menubar" ref={ref}>
      {menus.map((m, i) => (
        <li key={m.label}
            className={'w95-menubar-item' + (open === i ? ' w95-menubar-item--open' : '')}
            onMouseDown={(e) => { e.preventDefault(); setOpen(open === i ? null : i); }}
            onMouseEnter={() => { if (open !== null) setOpen(i); }}>
          {m.label}
          {open === i && (
            <ul className="w95-menu" style={{ position: 'absolute', left: 0, top: '100%', color: 'var(--w95-material-text)' }}>
              {m.items.map((it, j) => it.sep
                ? <li key={j} className="w95-menu-sep"></li>
                : (
                  <li key={j}
                      className={'w95-menu-item' + (it.disabled ? ' w95-menu-item--disabled' : '')}
                      onMouseDown={(e) => e.stopPropagation()}
                      onClick={() => { if (!it.disabled) { setOpen(null); it.onClick && it.onClick(); } }}>
                    {it.icon && <img src={ICON(it.icon)} alt="" />}
                    {it.label}
                  </li>
                ))}
            </ul>
          )}
        </li>
      ))}
    </ul>
  );
}

/* ---------------- Draggable Window ---------------- */
function Window({
  win, active, onFocus, onClose, onMinimize, onMaximize,
  width = 480, minHeight, children, menus, statusbar, icon, resizable = false, bodyStyle,
}) {
  const ref = useRef(null);
  const drag = useRef(null);

  const onPointerDown = (e) => {
    if (win.maximized) return;
    if (e.target.closest('.w95-titlebar-btn')) return;
    const el = ref.current;
    drag.current = { dx: e.clientX - el.offsetLeft, dy: e.clientY - el.offsetTop };
    el.setPointerCapture && e.target.setPointerCapture(e.pointerId);
    const move = (ev) => {
      if (!drag.current) return;
      const desk = el.parentElement;
      let x = ev.clientX - drag.current.dx;
      let y = ev.clientY - drag.current.dy;
      x = Math.max(-width + 60, Math.min(x, desk.clientWidth - 60));
      y = Math.max(0, Math.min(y, desk.clientHeight - 30));
      el.style.left = x + 'px';
      el.style.top = y + 'px';
    };
    const up = () => {
      drag.current = null;
      window.removeEventListener('pointermove', move);
      window.removeEventListener('pointerup', up);
    };
    window.addEventListener('pointermove', move);
    window.addEventListener('pointerup', up);
  };

  const maxStyle = win.maximized
    ? { left: 0, top: 0, width: '100%', height: '100%' }
    : { left: win.x, top: win.y, width };

  return (
    <div
      ref={ref}
      className="w95-window"
      data-screen-label={win.title}
      style={{
        position: 'absolute',
        zIndex: win.z,
        minHeight,
        display: 'flex',
        ...maxStyle,
      }}
      onMouseDown={() => onFocus(win.id)}
    >
      <div
        className={'w95-titlebar' + (active ? '' : ' w95-titlebar--inactive')}
        onPointerDown={onPointerDown}
        onDoubleClick={() => onMaximize && onMaximize(win.id)}
        style={{ cursor: win.maximized ? 'default' : 'default', touchAction: 'none' }}
      >
        {icon && <img src={ICON(icon)} alt="" />}
        <div className="w95-titlebar-title">{win.title}</div>
        <div className="w95-titlebar-options">
          {onMinimize && <button className="w95-btn w95-titlebar-btn" aria-label="Minimize" onClick={() => onMinimize(win.id)}><span style={{ marginTop: 6 }}>▬</span></button>}
          {onMaximize && <button className="w95-btn w95-titlebar-btn" aria-label="Maximize" onClick={() => onMaximize(win.id)}>{win.maximized ? '❐' : '□'}</button>}
          <button className="w95-btn w95-titlebar-btn" aria-label="Close" style={{ marginLeft: 4 }} onClick={() => onClose(win.id)}>✕</button>
        </div>
      </div>
      {menus && <MenuBar menus={menus} />}
      <div style={{ flexGrow: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden', ...bodyStyle }}>
        {children}
      </div>
      {statusbar && (
        <div className="w95-statusbar">
          {statusbar.map((s, i) => (
            <div key={i} className={'w95-statusbar-cell' + (i === 0 ? ' w95-statusbar-cell--grow' : '')}>{s}</div>
          ))}
        </div>
      )}
    </div>
  );
}

/* ---------------- Desktop icon ---------------- */
function DesktopIcon({ icon, label, selected, onSelect, onOpen }) {
  const lastTap = useRef(0);
  return (
    <div
      className={'w95-desktop-icon' + (selected ? ' w95-desktop-icon--selected' : '')}
      onMouseDown={(e) => { e.stopPropagation(); onSelect(); }}
      onDoubleClick={onOpen}
      onTouchEnd={() => {
        const now = Date.now();
        if (now - lastTap.current < 450) onOpen();
        lastTap.current = now;
      }}
      role="button"
      tabIndex={0}
      onKeyDown={(e) => { if (e.key === 'Enter') onOpen(); }}
    >
      <img src={ICON(icon)} alt="" draggable="false" />
      <div className="w95-icon-label">{label}</div>
    </div>
  );
}

/* ---------------- File icon (inside explorer windows) ---------------- */
function FileIcon({ icon, label, onOpen }) {
  const [sel, setSel] = useState(false);
  const lastTap = useRef(0);
  useEffect(() => {
    const clear = () => setSel(false);
    document.addEventListener('mousedown', clear);
    return () => document.removeEventListener('mousedown', clear);
  }, []);
  return (
    <div
      className={'w95-file-icon' + (sel ? ' w95-file-icon--selected' : '')}
      onMouseDown={(e) => { e.stopPropagation(); setSel(true); }}
      onDoubleClick={onOpen}
      onTouchEnd={() => {
        const now = Date.now();
        if (now - lastTap.current < 450) onOpen();
        lastTap.current = now;
      }}
      role="button" tabIndex={0}
      onKeyDown={(e) => { if (e.key === 'Enter') onOpen(); }}
    >
      <img src={ICON(icon)} alt="" draggable="false" />
      <div className="w95-icon-label">{label}</div>
    </div>
  );
}

/* ---------------- Taskbar ---------------- */
function Clock() {
  const [now, setNow] = useState(new Date());
  useEffect(() => {
    const t = setInterval(() => setNow(new Date()), 10000);
    return () => clearInterval(t);
  }, []);
  let h = now.getHours();
  const ampm = h >= 12 ? 'PM' : 'AM';
  h = h % 12 || 12;
  const m = String(now.getMinutes()).padStart(2, '0');
  return <span>{h}:{m} {ampm}</span>;
}

function Taskbar({ windows, activeId, onTaskClick, startOpen, onStartClick }) {
  return (
    <div style={{
      position: 'absolute', left: 0, right: 0, bottom: 0, height: 36,
      background: 'var(--w95-material)',
      boxShadow: 'inset 0 1px 0 0 var(--w95-border-lightest), inset 0 2px 0 0 var(--w95-border-light)',
      display: 'flex', alignItems: 'center', gap: 4, padding: '4px 4px 2px', zIndex: 3000,
    }}>
      <button
        className={'w95-btn' + (startOpen ? ' w95-btn--pressed' : '')}
        style={{ padding: startOpen ? '4px 8px 2px 10px' : '3px 9px 3px 9px', display: 'flex', alignItems: 'center', gap: 5, fontWeight: 'bold', flexShrink: 0 }}
        onClick={onStartClick}
        data-screen-label="Start button"
      >
        <img src={ICON('chip-flag')} style={{ width: 20, height: 20, imageRendering: 'pixelated' }} alt="" />
        Start
      </button>
      <div style={{ width: 1, alignSelf: 'stretch', margin: '2px 2px', borderLeft: '1px solid var(--w95-border-dark)', borderRight: '1px solid var(--w95-border-lightest)' }}></div>
      <div style={{ display: 'flex', gap: 4, flexGrow: 1, overflow: 'hidden' }}>
        {windows.map((w) => (
          <button key={w.id}
            className="w95-btn"
            style={{
              display: 'inline-flex', alignItems: 'center', gap: 5, maxWidth: 160, minWidth: 0, flexShrink: 1,
              padding: '3px 8px', fontWeight: w.id === activeId && !w.minimized ? 'bold' : 'normal',
              boxShadow: w.id === activeId && !w.minimized ? 'var(--w95-shadow-in)' : undefined,
              background: w.id === activeId && !w.minimized ? 'var(--w95-border-lighter)' : undefined,
            }}
            onClick={() => onTaskClick(w.id)}>
            {w.icon && <img src={ICON(w.icon)} style={{ width: 16, height: 16, imageRendering: 'pixelated', flexShrink: 0 }} alt="" />}
            <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{w.title}</span>
          </button>
        ))}
      </div>
      <div className="w95-well" style={{ marginLeft: 'auto', flexShrink: 0, padding: '4px 10px', display: 'flex', alignItems: 'center', gap: 7 }}>
        <img src={ICON('timedate-32')} style={{ width: 16, height: 16, imageRendering: 'pixelated' }} alt="" title="Time" />
        <Clock />
      </div>
    </div>
  );
}

/* ---------------- Start menu ---------------- */
/* items: [{label, icon, onClick, sub: [...], sep}] */
function StartMenu({ items, onClose }) {
  const [hot, setHot] = useState(null);
  const ref = useRef(null);
  useEffect(() => {
    const close = (e) => { if (ref.current && !ref.current.contains(e.target) && !e.target.closest('[data-screen-label="Start button"]')) onClose(); };
    document.addEventListener('mousedown', close);
    return () => document.removeEventListener('mousedown', close);
  }, [onClose]);
  return (
    <div ref={ref} data-screen-label="Start menu" style={{
      position: 'absolute', left: 2, bottom: 36, zIndex: 3500,
      background: 'var(--w95-material)', boxShadow: 'var(--w95-shadow-out)',
      display: 'flex', padding: 2,
    }}>
      <div style={{
        width: 24, background: 'linear-gradient(180deg, #00007f, #000e7a 60%, #1084d0)',
        display: 'flex', alignItems: 'flex-end', justifyContent: 'center', padding: '8px 0',
      }}>
        <span style={{
          writingMode: 'vertical-rl', transform: 'rotate(180deg)',
          color: '#c3c7cb', fontWeight: 'bold', fontSize: 14, letterSpacing: 1, whiteSpace: 'nowrap',
        }}><span style={{ color: '#fff' }}>Windows</span>Chip95</span>
      </div>
      <ul style={{ listStyle: 'none', margin: 0, padding: 0, minWidth: 200 }}>
        {items.map((it, i) => it.sep ? (
          <li key={i} className="w95-menu-sep" style={{ margin: '3px 4px' }}></li>
        ) : (
          <li key={i}
              onMouseEnter={() => setHot(i)}
              style={{
                display: 'flex', alignItems: 'center', gap: 10, padding: '5px 12px 5px 6px',
                background: hot === i ? 'var(--w95-header-bg)' : 'transparent',
                color: hot === i ? 'var(--w95-text-invert)' : 'inherit',
                position: 'relative', cursor: 'default', userSelect: 'none',
              }}
              onClick={() => { if (!it.sub) { onClose(); it.onClick && it.onClick(); } }}>
            <img src={ICON(it.icon)} style={{ width: 32, height: 32, imageRendering: 'pixelated' }} alt="" />
            <span style={{ flexGrow: 1 }}>{it.label}</span>
            {it.sub && <span style={{ fontSize: 9 }}>▶</span>}
            {it.sub && hot === i && (
              <ul className="w95-menu" style={{ position: 'absolute', left: '100%', top: -2 , color: 'var(--w95-material-text)'}}>
                {it.sub.map((s, j) => s.sep ? <li key={j} className="w95-menu-sep"></li> : (
                  <li key={j} className="w95-menu-item" style={{ padding: '5px 14px 5px 8px' }}
                      onClick={(e) => { e.stopPropagation(); onClose(); s.onClick && s.onClick(); }}>
                    {s.icon && <img src={ICON(s.icon)} style={{ width: 16, height: 16 }} alt="" />}
                    {s.label}
                  </li>
                ))}
              </ul>
            )}
          </li>
        ))}
      </ul>
    </div>
  );
}

/* ---------------- Simple modal dialog ---------------- */
function Dialog({ title, icon = 'warning-32', children, buttons, onClose, width = 360, z = 5000 }) {
  return (
    <div style={{ position: 'absolute', inset: 0, zIndex: z, display: 'grid', placeItems: 'center' }}>
      <div className="w95-window" style={{ width }} data-screen-label={'Dialog: ' + title}>
        <div className="w95-titlebar">
          <div className="w95-titlebar-title">{title}</div>
          <div className="w95-titlebar-options">
            <button className="w95-btn w95-titlebar-btn" onClick={onClose}>✕</button>
          </div>
        </div>
        <div style={{ display: 'flex', gap: 14, padding: '16px 14px', alignItems: 'flex-start' }}>
          <img src={ICON(icon)} style={{ width: 32, height: 32, imageRendering: 'pixelated', flexShrink: 0 }} alt="" />
          <div style={{ fontSize: 12, lineHeight: 1.45 }}>{children}</div>
        </div>
        <div style={{ display: 'flex', gap: 8, justifyContent: 'center', padding: '4px 10px 12px' }}>
          {(buttons || [{ label: 'OK', onClick: onClose, def: true }]).map((b, i) => (
            <W95Button key={i} def={b.def} style={{ minWidth: 80 }} onClick={b.onClick}>{b.label}</W95Button>
          ))}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { W95Button, MenuBar, Window, DesktopIcon, FileIcon, Taskbar, StartMenu, Dialog, ICON });
