import { useEffect, useRef, useState } from 'react';
import { useConnection } from '../../context/ConnectionContext';
import { useConsoleLog } from '../../context/ConsoleContext';
import { useServerData } from '../../context/ServerDataContext';
import { dispatchConsole } from '../../data/consoleDispatch';

/**
 * Runs command lines through the shared cambium-core grammar/executor
 * in-process (the same commands the `cambium` CLI runs — no /api/command).
 * The command list and syntax are in the published command reference.
 */
export function ConsolePanel() {
  const {
    api,
    orgName,
    projectName,
    account,
    deviceId,
    activeProjectId,
    workspacePath,
    refreshProjects,
  } = useConnection();
  const { refreshUsers, refreshRevisions, refreshDepotTree, refreshLocks } = useServerData();
  const { lines, appendLine, history, appendHistory } = useConsoleLog();
  const [input, setInput] = useState('');
  const [busy, setBusy] = useState(false);
  const [historyIndex, setHistoryIndex] = useState(null);
  const inputRef = useRef(null);
  const scrollRef = useRef(null);

  useEffect(() => {
    scrollRef.current?.scrollTo(0, scrollRef.current.scrollHeight);
  }, [lines]);

  const submit = async () => {
    const command = input.trim();
    if (!command || busy || !api) return;
    setInput('');
    appendHistory(command);
    setHistoryIndex(null);
    appendLine({ type: 'in', text: command });
    setBusy(true);
    const conn = { api, account, deviceId, activeProjectId, projectName, workspacePath };
    const refreshers = { refreshDepotTree, refreshRevisions, refreshLocks, refreshUsers, refreshProjects };
    const { result } = await dispatchConsole(command, conn, refreshers);
    setBusy(false);
    const text = result.output || (result.ok ? '' : 'No response.');
    appendLine({ type: result.ok ? 'out' : 'err', text });
  };

  const onKeyDown = (e) => {
    if (e.key === 'Enter') {
      e.preventDefault();
      submit();
      return;
    }
    if (e.key === 'ArrowUp') {
      e.preventDefault();
      if (!history.length) return;
      const next = historyIndex == null ? history.length - 1 : Math.max(0, historyIndex - 1);
      setHistoryIndex(next);
      setInput(history[next]);
      return;
    }
    if (e.key === 'ArrowDown') {
      e.preventDefault();
      if (historyIndex == null) return;
      const next = historyIndex + 1;
      if (next >= history.length) {
        setHistoryIndex(null);
        setInput('');
      } else {
        setHistoryIndex(next);
        setInput(history[next]);
      }
    }
  };

  return (
    <div
      className="console-container"
      ref={scrollRef}
      onClick={() => inputRef.current?.focus()}
    >
      <div className="console-banner">
        Connected to {orgName}
        {projectName ? ` / ${projectName}` : ''} as {account?.username} ({account?.deviceName})
      </div>
      <div className="console-modules">
        Same commands as the cambium CLI — type &quot;help&quot;.
      </div>
      {lines.map((line, index) => (
        <div
          key={index}
          className={
            line.type === 'in'
              ? 'console-line console-line--input'
              : line.type === 'err'
                ? 'console-line console-line--error'
                : 'console-line'
          }
        >
          {line.type === 'in' ? `> ${line.text}` : line.text}
        </div>
      ))}
      <div className="console-prompt">
        <span className="console-prompt-symbol">&gt;</span>
        <input
          ref={inputRef}
          className="console-input"
          type="text"
          value={input}
          disabled={busy}
          onChange={(e) => setInput(e.target.value)}
          onKeyDown={onKeyDown}
          spellCheck={false}
          autoComplete="off"
        />
      </div>
    </div>
  );
}
