/* global React */

const { useState: useTState, useEffect: useTEffect, useRef: useTRef } = React;

/* ============================================================
   Interactive terminal prompt — the hero centerpiece
   ============================================================ */

const BOOT_LINES = [
  "Welcome. Type `help` or click a command below.",
  "",
];

const COMMANDS = {
  help: {
    desc: "list commands",
    run: () => [
      "Available commands:",
      "  services   → what I do for home service companies",
      "  process    → how an engagement works",
      "  cases      → past wins (anonymized)",
      "  pricing    → what it costs",
      "  about      → who is this guy",
      "  stack      → the software I'm opinionated about",
      "  book       → schedule a call (opens contact form)",
      "  whoami     → who you are, probably",
      "  clear      → wipe the screen",
      "  sudo make-me-a-sandwich → don't.",
      "",
    ],
  },
  services: {
    desc: "core services",
    run: () => [
      "1. Tech Stack Audit        : 2 wk · $4,500 flat",
      "2. AI Implementation       : 6-10 wk · from $18K",
      "3. Agent Build             : 4-8 wk · from $12K",
      "4. Fractional Consultation : monthly · from $3.5K/mo",
      "",
      "See #services below for details, or run `pricing`.",
      "",
    ],
    jump: '#services',
  },
  process: {
    desc: "engagement flow",
    run: () => [
      "1. DIAGNOSTIC  → a 45-min free call. Bring your weirdest problem.",
      "2. PROPOSAL    → scoped, fixed-price, written in plain English.",
      "3. BUILD       → weekly demos. No two-month dark rooms.",
      "4. HANDOFF     → docs, loom walkthroughs, and a 30-day tune-up.",
      "",
    ],
    jump: '#process',
  },
  cases: {
    desc: "past wins",
    run: () => [
      "• Midwest HVAC, $6M     : AI dispatcher saved 9 hrs/wk, +14% bookings",
      "• Regional plumber      : ServiceTitan to HubSpot sync, quote-to-cash in 1 day",
      "• Lawn care franchise  : agent handles route replanning after rain",
      "• Pest control chain   : call summary agent + CRM auto-update",
      "",
    ],
    jump: '#cases',
  },
  pricing: {
    desc: "what it costs",
    run: () => [
      "Fixed-price. Written down. Nobody likes hourly.",
      "  ▸ Audit         $4,500",
      "  ▸ Agent Build   from $12,000",
      "  ▸ AI Impl.      from $18,000",
      "  ▸ Fractional    from $3,500/mo (min 3 mo)",
      "",
    ],
    jump: '#pricing',
  },
  about: {
    desc: "founder story",
    run: () => [
      "Hi, I'm Jamie. 14 years as a software engineer at two SaaS companies",
      "you've heard of. My dad ran an HVAC shop and I watched him print out",
      "dispatch spreadsheets at 5am. I built this so that stops happening.",
      "",
    ],
    jump: '#about',
  },
  stack: {
    desc: "opinionated stack",
    run: () => [
      "Dispatch/CRM : ServiceTitan · Housecall Pro · Jobber · HCP",
      "AI/Agents    : Claude · LangGraph · Make · n8n · Zapier",
      "Voice        : Retell · Vapi · Bland",
      "Data         : Supabase · Postgres · Metabase",
      "Everything else is probably a Google Sheet. That's fine.",
      "",
    ],
  },
  book: {
    desc: "book a call",
    run: () => [
      "Opening contact form ...",
      "Pro tip: tell me your #1 time-suck in one sentence.",
      "",
    ],
    jump: '#contact',
  },
  whoami: {
    desc: "guess",
    run: () => [
      "A home service operator who clicked 'CTO' on Google and ended up here.",
      "Welcome. Run `help` to see what's on the menu.",
      "",
    ],
  },
  clear: {
    desc: "clear screen",
    run: () => "__CLEAR__",
  },
  "sudo make-me-a-sandwich": {
    desc: "don't",
    hidden: true,
    run: () => ["Permission denied. This is a consulting firm, not a deli.", ""],
  },
  ls: {
    desc: "list",
    hidden: true,
    run: () => ["services/  process/  cases/  pricing/  about/  reading/  contact/", ""],
  },
  "rm -rf /": {
    desc: "no",
    hidden: true,
    run: () => ["Nope. Not today. (But I love your chaotic energy.)", ""],
  },
};

function TerminalHero() {
  const [lines, setLines] = useTState([]);
  const [input, setInput] = useTState('');
  const [history, setHistory] = useTState([]);
  const [histIdx, setHistIdx] = useTState(-1);
  const [booted, setBooted] = useTState(false);
  const inputRef = useTRef(null);
  const bodyRef = useTRef(null);

  // Boot sequence
  useTEffect(() => {
    let cancelled = false;
    (async () => {
      for (let i = 0; i < BOOT_LINES.length; i++) {
        await new Promise(r => setTimeout(r, i === 0 ? 80 : (i === 3 || i === 4 ? 220 : 110)));
        if (cancelled) return;
        setLines(prev => [...prev, { kind: 'boot', text: BOOT_LINES[i] }]);
      }
      setBooted(true);
    })();
    return () => { cancelled = true; };
  }, []);

  // autoscroll
  useTEffect(() => {
    if (bodyRef.current) bodyRef.current.scrollTop = bodyRef.current.scrollHeight;
  }, [lines]);

  // focus
  useTEffect(() => {
    if (booted && inputRef.current) inputRef.current.focus();
  }, [booted]);

  const runCommand = (raw) => {
    const cmd = raw.trim();
    if (!cmd) {
      setLines(prev => [...prev, { kind: 'prompt', text: '' }]);
      return;
    }
    setHistory(h => [...h, cmd]);
    setHistIdx(-1);

    const entry = COMMANDS[cmd.toLowerCase()] || COMMANDS[cmd];
    const promptLine = { kind: 'prompt', text: cmd };

    if (!entry) {
      setLines(prev => [
        ...prev,
        promptLine,
        { kind: 'err', text: `command not found: ${cmd}` },
        { kind: 'err', text: `try \`help\`` },
        { kind: 'out', text: '' },
      ]);
      return;
    }

    const out = entry.run();
    if (out === '__CLEAR__') {
      setLines([]);
      return;
    }
    const outLines = (Array.isArray(out) ? out : [out]).map(t => ({ kind: 'out', text: t }));
    setLines(prev => [...prev, promptLine, ...outLines]);

    if (entry.navigate) {
      setTimeout(() => { window.location.href = entry.navigate; }, 500);
    } else if (entry.jump) {
      setTimeout(() => {
        const el = document.querySelector(entry.jump);
        if (el) el.scrollIntoView ? el.scrollIntoView({ behavior: 'smooth', block: 'start' }) : null;
      }, 300);
    }
  };

  // NOTE: avoid scrollIntoView on html element; use window.scrollTo instead
  const scrollToHash = (hash) => {
    const el = document.querySelector(hash);
    if (el) {
      const y = el.getBoundingClientRect().top + window.scrollY - 80;
      window.scrollTo({ top: y, behavior: 'smooth' });
    }
  };

  const handleKey = (e) => {
    if (e.key === 'Enter') {
      const cmd = input;
      setInput('');
      // handle jump without scrollIntoView
      const entry = COMMANDS[cmd.trim().toLowerCase()];
      if (entry && entry.jump) {
        setTimeout(() => scrollToHash(entry.jump), 250);
      }
      runCommand(cmd);
    } else if (e.key === 'ArrowUp') {
      e.preventDefault();
      if (history.length === 0) return;
      const ni = histIdx < 0 ? history.length - 1 : Math.max(0, histIdx - 1);
      setHistIdx(ni);
      setInput(history[ni]);
    } else if (e.key === 'ArrowDown') {
      e.preventDefault();
      if (histIdx < 0) return;
      const ni = histIdx + 1;
      if (ni >= history.length) {
        setHistIdx(-1);
        setInput('');
      } else {
        setHistIdx(ni);
        setInput(history[ni]);
      }
    } else if (e.key === 'Tab') {
      e.preventDefault();
      const partial = input.toLowerCase();
      const match = Object.keys(COMMANDS).find(k => k.startsWith(partial) && !COMMANDS[k].hidden);
      if (match) setInput(match);
    }
  };

  const quickCmds = ['services', 'process', 'cases', 'pricing', 'about', 'book'];

  return (
    <CRTFrame style={{ maxWidth: 860 }}>
      <div
        ref={bodyRef}
        onClick={() => inputRef.current && inputRef.current.focus()}
        style={{
          height: 240,
          overflowY: 'auto',
          fontSize: 14,
          lineHeight: 1.55,
          cursor: 'text',
        }}
      >
        {lines.map((l, i) => {
          if (l.kind === 'boot') {
            return <div key={i} style={{ color: 'var(--fg-dim)' }}>{l.text || '\u00A0'}</div>;
          }
          if (l.kind === 'prompt') {
            return (
              <div key={i}>
                <span className="prompt"><span className="sym">$</span> hsc&gt; </span>
                <span className="bright">{l.text}</span>
              </div>
            );
          }
          if (l.kind === 'err') {
            return <div key={i} style={{ color: 'var(--accent-2)' }}>{l.text}</div>;
          }
          return <div key={i} style={{ whiteSpace: 'pre' }}>{l.text || '\u00A0'}</div>;
        })}

        {/* live input */}
        {booted && (
          <div style={{ display: 'flex', alignItems: 'center' }}>
            <span className="prompt"><span className="sym">$</span>&nbsp;hsc&gt;&nbsp;</span>
            <input
              ref={inputRef}
              value={input}
              onChange={e => setInput(e.target.value)}
              onKeyDown={handleKey}
              autoFocus
              spellCheck={false}
              style={{
                flex: 1,
                background: 'transparent',
                border: 'none',
                outline: 'none',
                color: 'var(--fg-bright)',
                fontFamily: 'inherit',
                fontSize: 'inherit',
                caretColor: 'var(--fg)',
              }}
            />
          </div>
        )}
      </div>

      <div style={{
        marginTop: '1rem',
        paddingTop: '0.8rem',
        borderTop: '1px dashed var(--border)',
        display: 'flex',
        flexWrap: 'wrap',
        gap: '0.5rem',
        fontSize: 12,
      }}>
        <span className="muted" style={{ marginRight: '0.5em' }}>try:</span>
        {quickCmds.map(c => (
          <button
            key={c}
            onClick={() => { runCommand(c); inputRef.current && inputRef.current.focus(); }}
            style={{
              background: 'transparent',
              border: '1px solid var(--border)',
              color: 'var(--fg)',
              padding: '0.15em 0.6em',
              fontFamily: 'inherit',
              fontSize: 12,
              cursor: 'pointer',
              letterSpacing: '0.05em',
            }}
            onMouseEnter={e => { e.currentTarget.style.background = 'var(--bg-3)'; e.currentTarget.style.borderColor = 'var(--fg-dim)'; }}
            onMouseLeave={e => { e.currentTarget.style.background = 'transparent'; e.currentTarget.style.borderColor = 'var(--border)'; }}
          >
            ▸ {c}
          </button>
        ))}
      </div>
    </CRTFrame>
  );
}

Object.assign(window, { TerminalHero });
