// Terminal.jsx — the interactive shell view
// Depends on: window.__shell, React

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

// ─── Themes ───────────────────────────────────────────────────
const THEMES = {
  'tokyo-night': {
    label: 'Tokyo Night',
    bg: '#1a1b26',
    chrome: '#16171f',
    fg: '#c0caf5',
    muted: '#565f89',
    accent: '#7aa2f7',
    user: '#9ece6a',
    host: '#bb9af7',
    dir: '#7dcfff',
    error: '#f7768e',
    selection: '#33467c',
  },
  'one-dark': {
    label: 'One Dark',
    bg: '#282c34',
    chrome: '#21252b',
    fg: '#abb2bf',
    muted: '#5c6370',
    accent: '#61afef',
    user: '#98c379',
    host: '#c678dd',
    dir: '#56b6c2',
    error: '#e06c75',
    selection: '#3e4451',
  },
  'crt-green': {
    label: 'CRT Green',
    bg: '#0a0e0a',
    chrome: '#050705',
    fg: '#9fe89f',
    muted: '#4a7a4a',
    accent: '#b8ffb8',
    user: '#e0ffe0',
    host: '#7acc7a',
    dir: '#b8ffb8',
    error: '#ff9999',
    selection: '#1e3a1e',
  },
  'solarized-warm': {
    label: 'Solarized Warm',
    bg: '#1c1411',
    chrome: '#120b09',
    fg: '#e8d5b7',
    muted: '#8a7a66',
    accent: '#d08a4a',
    user: '#a8b96a',
    host: '#c79a6a',
    dir: '#6aa8b9',
    error: '#d06a6a',
    selection: '#3a2d22',
  },
  'mono-paper': {
    label: 'Mono Paper',
    bg: '#f4f1ea',
    chrome: '#e8e4db',
    fg: '#2a2a2a',
    muted: '#888580',
    accent: '#b85c38',
    user: '#2a2a2a',
    host: '#5a5a5a',
    dir: '#3a3a3a',
    error: '#b83838',
    selection: '#d8d4ca',
  },
  'monokai': {
    label: 'Monokai',
    bg: '#272822',
    chrome: '#1e1f1a',
    fg: '#f8f8f2',
    muted: '#75715e',
    accent: '#66d9ef',
    user: '#a6e22e',
    host: '#ae81ff',
    dir: '#fd971f',
    error: '#f92672',
    selection: '#49483e',
  },
};

const FONTS = {
  'jetbrains-mono': { label: 'JetBrains Mono', stack: '"JetBrains Mono", ui-monospace, monospace' },
  'fira-code': { label: 'Fira Code', stack: '"Fira Code", ui-monospace, monospace' },
  'ibm-plex-mono': { label: 'IBM Plex Mono', stack: '"IBM Plex Mono", ui-monospace, monospace' },
  'space-mono': { label: 'Space Mono', stack: '"Space Mono", ui-monospace, monospace' },
  'system-mono': { label: 'System Mono', stack: 'ui-monospace, "SF Mono", "Menlo", monospace' },
};

const PROMPT_STYLES = {
  'classic': (u, h, p) => <><span className="user">{u}@{h}</span><span className="muted">:</span><span className="dir">{p}</span><span className="muted">$ </span></>,
  'arrow': (u, h, p) => <><span className="dir">{p}</span> <span className="accent">❯ </span></>,
  'minimal': (u, h, p) => <><span className="muted">{p} </span><span className="fg">λ </span></>,
  'bracket': (u, h, p) => <><span className="muted">[</span><span className="user">{u}</span> <span className="dir">{p}</span><span className="muted">]</span><span className="accent"> ❯ </span></>,
};

// ─── Boot log lines ───────────────────────────────────────────
const BOOT_LINES = [
  { t: 0,   text: '[    0.000000] OS version works-on-my-machine (luis@workstation)' },
  { t: 80,  text: '[    0.012430] Command line: BOOT_IMAGE=/boot/vmlinuz root=/dev/sda1 ro quiet splash' },
  { t: 140, text: '[    0.108221] CPU: Intel(R) Core(TM) i7-7700HQ @ 2.80GHz' },
  { t: 180, text: '[    0.312008] Memory: 16384256K/16777216K available' },
  { t: 240, text: '[    0.614500] systemd[1]: Starting Portfolio Service...' },
  { t: 320, text: '[    0.892114] systemd[1]: Mounted /home/luis.' },
  { t: 380, text: '[    1.024884] systemd[1]: Started Session 1 of user luis.' },
  { t: 450, text: '' },
  { t: 460, text: 'works-on-my-machine 26.04 LTS tty1', className: 'accent' },
  { t: 470, text: 'luis@portfolio: type "help" or "cat README.md" to begin.', className: 'muted' },
  { t: 480, text: '' },
];

// ─── Terminal component ──────────────────────────────────────
function Terminal({ settings, onToggleTweaks }) {
  const theme = THEMES[settings.theme] || THEMES['tokyo-night'];
  const font = FONTS[settings.font] || FONTS['jetbrains-mono'];
  const promptFn = PROMPT_STYLES[settings.prompt] || PROMPT_STYLES.classic;

  const [cwd, setCwd] = useState([]);
  const [lines, setLines] = useState([]); // rendered output blocks
  const [input, setInput] = useState('');
  const [history, setHistory] = useState([]);
  const [histIdx, setHistIdx] = useState(-1);
  const [pager, setPager] = useState(null); // {title, content}
  const [booted, setBooted] = useState(false);
  const inputRef = useRef(null);
  const scrollRef = useRef(null);

  // Boot animation — always runs once on mount
  useEffect(() => {
    const timers = [];
    BOOT_LINES.forEach((line) => {
      timers.push(setTimeout(() => {
        setLines(prev => [...prev, { kind: 'boot', text: line.text, className: line.className }]);
      }, line.t));
    });
    timers.push(setTimeout(() => setBooted(true), BOOT_LINES[BOOT_LINES.length - 1].t + 200));
    return () => timers.forEach(clearTimeout);
  }, []);

  // Autoscroll
  useEffect(() => {
    if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
  }, [lines, input, booted]);

  // Focus input on click anywhere in terminal
  useEffect(() => {
    const onClick = (e) => {
      // Don't steal focus if user is selecting text or clicking tweaks panel
      if (window.getSelection && window.getSelection().toString()) return;
      if (e.target.closest('.tweaks-panel')) return;
      if (e.target.closest('.tweaks-toggle')) return;
      inputRef.current?.focus();
    };
    const el = scrollRef.current?.parentElement;
    el?.addEventListener('click', onClick);
    return () => el?.removeEventListener('click', onClick);
  }, []);

  const runCommand = useCallback((raw) => {
    const promptLine = { kind: 'prompt', cwd: [...cwd], text: raw };
    const result = window.__shell.execute(raw, { cwd, history });

    if (result.clear) {
      setLines([]);
      if (raw.trim()) setHistory(h => [...h, raw.trim()]);
      setHistIdx(-1);
      return;
    }

    if (result.pager) {
      setLines(prev => [...prev, promptLine]);
      setPager(result.pager);
      if (raw.trim()) setHistory(h => [...h, raw.trim()]);
      setHistIdx(-1);
      return;
    }

    setLines(prev => [...prev, promptLine, ...(result.output || []).map(o => ({ kind: 'out', content: o }))]);
    if (result.newCwd) setCwd(result.newCwd);
    if (raw.trim()) setHistory(h => [...h, raw.trim()]);
    setHistIdx(-1);
  }, [cwd, history]);

  const onKeyDown = (e) => {
    // While the pager is open, absorb input; 'q' or Esc closes it
    if (pager) {
      if (e.key === 'q' || e.key === 'Q' || e.key === 'Escape') {
        e.preventDefault();
        setPager(null);
      }
      return;
    }
    if (e.key === 'Enter') {
      e.preventDefault();
      runCommand(input);
      setInput('');
    } else if (e.key === 'Tab') {
      e.preventDefault();
      const completed = window.__shell.complete(input, cwd);
      if (completed !== input) setInput(completed);
    } else if (e.key === 'ArrowUp') {
      e.preventDefault();
      if (!history.length) return;
      const next = histIdx === -1 ? history.length - 1 : Math.max(0, histIdx - 1);
      setHistIdx(next);
      setInput(history[next]);
    } else if (e.key === 'ArrowDown') {
      e.preventDefault();
      if (histIdx === -1) return;
      const next = histIdx + 1;
      if (next >= history.length) { setHistIdx(-1); setInput(''); }
      else { setHistIdx(next); setInput(history[next]); }
    } else if (e.key === 'l' && (e.ctrlKey || e.metaKey)) {
      e.preventDefault();
      setLines([]);
    } else if (e.key === 'c' && e.ctrlKey) {
      // ctrl-c: cancel current line
      e.preventDefault();
      setLines(prev => [...prev, { kind: 'prompt', cwd: [...cwd], text: input + '^C' }]);
      setInput('');
      setHistIdx(-1);
    }
  };

  const pathStr = window.__shell.pathToString(cwd);

  return (
    <div className="terminal-root" style={{
      '--bg': theme.bg,
      '--chrome': theme.chrome,
      '--fg': theme.fg,
      '--muted': theme.muted,
      '--accent': theme.accent,
      '--user': theme.user,
      '--host': theme.host,
      '--dir': theme.dir,
      '--error': theme.error,
      '--selection': theme.selection,
      '--font': font.stack,
      '--size': settings.fontSize + 'px',
    }}>
      {/* Window chrome */}
      <div className="window-chrome">
        <div className="traffic-lights">
          <span className="tl tl-close" />
          <span className="tl tl-min" />
          <span className="tl tl-max" />
        </div>
        <div className="window-title">luis@portfolio: {pathStr}</div>
        <div className="window-spacer" />
      </div>

      {/* Terminal body */}
      <div className="term-body" ref={scrollRef}>
        {lines.map((line, i) => <LineView key={i} line={line} promptFn={promptFn} />)}

        {/* Current input line */}
        {booted && !pager && (
          <div className="input-line">
            {promptFn('luis', 'portfolio', pathStr)}
            <div className="input-wrap">
              <input
                ref={inputRef}
                className="term-input"
                value={input}
                onChange={e => setInput(e.target.value)}
                onKeyDown={onKeyDown}
                autoFocus
                autoComplete="off"
                autoCorrect="off"
                autoCapitalize="off"
                spellCheck={false}
              />
              <Cursor text={input} />
            </div>
          </div>
        )}

        {/* Pager view (less) */}
        {pager && (
          <Pager title={pager.title} content={pager.content} onClose={() => setPager(null)} />
        )}
      </div>
    </div>
  );
}

// Pager (less): full takeover of the body, press q / Esc to close
function Pager({ title, content, onClose }) {
  useEffect(() => {
    const onKey = (e) => {
      if (e.key === 'q' || e.key === 'Q' || e.key === 'Escape') {
        e.preventDefault();
        onClose();
      }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [onClose]);
  return (
    <div className="pager">
      <pre className="pager-content">{content}</pre>
      <div className="pager-status">
        <span className="pager-title">{title}</span>
        <span className="pager-hint">press <b>q</b> to quit</span>
      </div>
    </div>
  );
}

// Render a single output line
function LineView({ line, promptFn }) {
  if (line.kind === 'boot') {
    return <div className={'line ' + (line.className || 'muted')}>{line.text || '\u00A0'}</div>;
  }
  if (line.kind === 'prompt') {
    const pathStr = window.__shell.pathToString(line.cwd);
    return (
      <div className="line">
        {promptFn('luis', 'portfolio', pathStr)}
        <span>{line.text}</span>
      </div>
    );
  }
  if (line.kind === 'out') {
    const c = line.content;
    if (typeof c === 'string') return <div className="line">{c || '\u00A0'}</div>;
    if (c && c.type === 'whoami') return <Whoami />;
    if (c && c.type === 'ls') {
      return (
        <div className="ls-grid">
          {c.entries.map((e, i) => (
            <span key={i} className={e.isDir ? 'dir' : ''}>
              {e.name}{e.isDir ? '/' : ''}
            </span>
          ))}
        </div>
      );
    }
    const cls = (c && c.className) || '';
    const text = (c && c.text) || '';
    return <div className={'line ' + cls}>{text || '\u00A0'}</div>;
  }
  return null;
}

// Blinking cursor overlaid on the input
function Cursor({ text }) {
  return (
    <span className="cursor-wrap">
      <span className="cursor-measure">{text}</span>
      <span className="cursor" />
    </span>
  );
}

// Whoami — portrait + system/owner info
function Whoami() {
  const host = (typeof window !== 'undefined' && window.location && window.location.host) || 'localhost';
  const rows = [
    { k: 'Host',      v: host },
    { k: 'Uptime',    v: '8 years · no reboots' },
    { k: 'Shell',     v: 'bash 5.2 · trilingual · mildly opinionated' },
    { k: 'Location',  v: 'Charlotte, NC' },
    { k: 'Role',      v: 'Senior Software Engineer' },
    { k: 'Languages', v: 'Spanish · English · French · Chinese' },
    { k: 'Likes',     v: 'sports · ambitious cooking · AI that actually ships' },
    { k: 'Contact',   v: 'type `open github` | `open linkedin` | `open email`' },
  ];
  return (
    <div className="whoami">
      <div className="whoami-avatar-wrap">
        <img src="assets/avatar.jpeg" alt="Luis Cavanillas" className="whoami-avatar" />
        <div className="whoami-colorbar">
          <span/>
          <span/>
          <span/>
          <span/>
          <span/>
          <span/>
        </div>
      </div>
      <div className="whoami-info">
        {rows.map((r, i) => {
          if (r.sep) return <div key={i} className="whoami-sep">{'─'.repeat(34)}</div>;
          if (r.head) return (
            <div key={i} className="whoami-head">
              <span className="user">{r.k}</span><span className="muted">{r.v}</span>
            </div>
          );
          return (
            <div key={i} className="whoami-row">
              <span className="accent whoami-key">{r.k}</span>
              <span>{r.v}</span>
            </div>
          );
        })}
      </div>
    </div>
  );
}

Object.assign(window, { Terminal, THEMES, FONTS, PROMPT_STYLES });
