const termPalettes = {
  green:  { bg: "#0a0f0a", fg: "#c8f7c5", dim: "#6b8a6b", accent: "#7dfc82", muted: "#3a4a3a" },
  amber:  { bg: "#120d05", fg: "#f3d488", dim: "#8a7548", accent: "#ffbf47", muted: "#4a3a1a" },
  mono:   { bg: "#0b0b0c", fg: "#e6e6e6", dim: "#7a7a7a", accent: "#ffffff", muted: "#3a3a3a" },
};

function TerminalVariant({ backend, personality, density, accent, fontPair, bubble }) {
  const { messages, pending, debug, send, reset } = useFetchChat({ backend, personality });
  const suggestions = useRotatingSuggestions({ visible: 3 });
  const [input, setInput] = React.useState("");
  const [showDebug, setShowDebug] = React.useState(false);
  const scrollRef = React.useRef(null);
  const inputRef = React.useRef(null);

  const palette = termPalettes[accent] || termPalettes.green;

  const lineHeight = density === "compact" ? 1.35 : density === "cozy" ? 1.75 : 1.55;
  const pad = density === "compact" ? 16 : density === "cozy" ? 32 : 24;

  React.useEffect(() => {
    const el = scrollRef.current;
    if (el) el.scrollTop = el.scrollHeight;
  }, [messages.length, pending]);

  React.useEffect(() => {
    const onKey = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "d") {
        e.preventDefault();
        setShowDebug(s => !s);
      }
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
        e.preventDefault();
        reset();
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [reset]);

  const submit = (e) => {
    e?.preventDefault();
    const v = input.trim();
    if (!v || pending) return;
    setInput("");
    send(v);
  };

  const quickSend = (text) => {
    if (pending) return;
    send(text);
  };

  return (
    <div style={{
      position: "absolute", inset: 0,
      background: palette.bg, color: palette.fg,
      fontFamily: fontPair.mono,
      fontSize: 14, lineHeight,
      display: "flex", flexDirection: "column",
      overflow: "hidden",
    }}>
      <header style={{
        display: "flex", alignItems: "center", justifyContent: "space-between",
        padding: `10px ${pad}px`,
        borderBottom: `1px solid ${palette.muted}`,
        color: palette.dim, fontSize: 12,
      }}>
        <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
          <span style={{ color: palette.accent }}>◉</span>
          <span>fetch pup · demo, static</span>
        </div>
        <div style={{ display: "flex", gap: 16 }}>
          <button onClick={reset} style={termBtn(palette)}>clear ⌘K</button>
          <button onClick={() => setShowDebug(s => !s)} style={termBtn(palette)}>
            debug ⌘D
          </button>
        </div>
      </header>

      <div ref={scrollRef} style={{
        flex: 1, overflowY: "auto",
        padding: `${pad}px ${pad * 1.5}px`,
        scrollbarWidth: "thin", scrollbarColor: `${palette.muted} transparent`,
      }}>
        <pre style={{
          margin: 0, fontFamily: "inherit", color: palette.dim,
          whiteSpace: "pre-wrap", marginBottom: 16,
        }}>
{`// this is fetch pup, a dog-loving chatbot and learning baseline.
// it works with intent matching, keyword lookup and fallbacks. no model, all browser.
// ask a question and hit enter, or try the suggestions below.
`}
        </pre>

        {messages.filter(m => !m.pending).map((m) => (
          <TerminalLine
            key={m.id}
            msg={m}
            palette={palette}
          />
        ))}
        {pending && <BlinkingCursor palette={palette} label="fetching an answer" />}
      </div>

      <form onSubmit={submit} style={{
        padding: `${pad - 4}px ${pad * 1.5}px ${pad}px`,
        borderTop: `1px solid ${palette.muted}`,
        display: "flex", flexDirection: "column", gap: 10,
      }}>
        <SuggestionsRow
          suggestions={suggestions}
          onPick={quickSend}
          palette={palette}
          pending={pending}
        />
        <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
          <span style={{ color: palette.accent, userSelect: "none" }}>fetch&gt;</span>
          <input
            ref={inputRef}
            value={input}
            onChange={e => setInput(e.target.value)}
            placeholder={pending ? "…waiting on fetch" : "ask something"}
            autoFocus
            disabled={pending}
            style={{
              flex: 1, background: "transparent", border: "none", outline: "none",
              color: palette.fg, fontFamily: "inherit", fontSize: 14, caretColor: palette.accent,
            }}
          />
          <button type="submit" disabled={pending || !input.trim()} style={{
            ...termBtn(palette),
            color: palette.accent, borderColor: palette.accent,
            opacity: pending || !input.trim() ? 0.4 : 1,
          }}>↵ send</button>
        </div>
      </form>

      {showDebug && (
        <DebugPanel
          debug={debug}
          onClose={() => setShowDebug(false)}
          palette={{ bg: palette.bg, fg: palette.fg, dim: palette.dim, accent: palette.accent, muted: palette.muted }}
          font={fontPair.mono}
        />
      )}
    </div>
  );
}

function termBtn(p) {
  return {
    background: "transparent",
    color: p.dim,
    border: `1px solid ${p.muted}`,
    padding: "3px 8px",
    borderRadius: 4,
    fontFamily: "inherit",
    fontSize: 13,
    cursor: "pointer",
    letterSpacing: 0.3,
  };
}

function TerminalLine({ msg, palette }) {
  const isUser = msg.role === "user";
  const prefix = isUser ? "you$" : "fetch#";
  const color = isUser ? palette.fg : palette.accent;
  const [mounted, setMounted] = React.useState(false);
  React.useEffect(() => {
    const id = requestAnimationFrame(() => setMounted(true));
    return () => cancelAnimationFrame(id);
  }, []);
  return (
    <div style={{
      marginBottom: 10,
      opacity: mounted ? 1 : 0,
      transform: mounted ? "translateY(0)" : "translateY(4px)",
      transition: "opacity .18s ease, transform .18s ease",
    }}>
      {!isUser && msg.fact && !msg.pending && (
        <div style={{ color: palette.dim, fontStyle: "italic", marginBottom: 2 }}>
          {`// fact matched: ${msg.fact.keyword}`}
        </div>
      )}
      <div>
        <span style={{ color: palette.dim, userSelect: "none" }}>{prefix} </span>
        <span style={{ color, whiteSpace: "pre-wrap" }}>
          {msg.pending ? <DotDotDot palette={palette} /> : msg.content}
        </span>
      </div>
    </div>
  );
}

function DotDotDot({ palette }) {
  const [n, setN] = React.useState(1);
  React.useEffect(() => {
    const id = setInterval(() => setN(x => (x % 3) + 1), 380);
    return () => clearInterval(id);
  }, []);
  return <span style={{ color: palette.dim }}>{".".repeat(n)}</span>;
}

function BlinkingCursor({ palette, label }) {
  return (
    <div style={{ color: palette.dim, fontStyle: "italic", marginTop: 4 }}>
      {label}
      <span className="fetch-blink" style={{
        display: "inline-block", width: 8, height: 14, marginLeft: 6,
        verticalAlign: "middle", background: palette.accent, opacity: 0.7,
      }}/>
    </div>
  );
}

function SuggestionsRow({ suggestions, onPick, palette, pending }) {
  return (
    <div style={{
      display: "flex", gap: 8, flexWrap: "wrap", alignItems: "center",
      color: palette.dim, fontSize: 13,
    }}>
      <span style={{ opacity: 0.7 }}>try:</span>
      {suggestions.map((s, i) => (
        <button
          key={s}
          type="button"
          disabled={pending}
          onClick={() => onPick(s)}
          style={{
            ...termBtn(palette),
            padding: "2px 8px",
            fontSize: 13,
            cursor: pending ? "default" : "pointer",
            opacity: pending ? 0.5 : 1,
            animation: `fetch-fadein .4s ease ${i * 60}ms both`,
          }}
        >{s}</button>
      ))}
    </div>
  );
}

Object.assign(window, { TerminalVariant });
