import { useState, useRef, useEffect, useCallback } from "react";
import { cn } from "@/lib/utils";
import {
  X,
  Terminal as TerminalIcon,
  Trash2,
  Copy,
  Check,
  Loader2,
} from "lucide-react";

interface TerminalLine {
  id: number;
  type: "input" | "output" | "error" | "info";
  text: string;
  timestamp: number;
}

interface TerminalPanelProps {
  open: boolean;
  onClose: () => void;
}

export function TerminalPanel({ open, onClose }: TerminalPanelProps) {
  const [lines, setLines] = useState<TerminalLine[]>([
    {
      id: 0,
      type: "info",
      text: "Claw Terminal v1.0 — Type commands below. Use Ctrl+C to cancel.",
      timestamp: Date.now(),
    },
  ]);
  const [input, setInput] = useState("");
  const [isRunning, setIsRunning] = useState(false);
  const [cwd, setCwd] = useState("/home/ubuntu");
  const [history, setHistory] = useState<string[]>([]);
  const [historyIndex, setHistoryIndex] = useState(-1);
  const [copied, setCopied] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);
  const scrollRef = useRef<HTMLDivElement>(null);
  const lineIdRef = useRef(1);

  // Auto-scroll to bottom
  useEffect(() => {
    if (scrollRef.current) {
      scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
    }
  }, [lines]);

  // Focus input when panel opens
  useEffect(() => {
    if (open) {
      setTimeout(() => inputRef.current?.focus(), 100);
    }
  }, [open]);

  const addLine = useCallback(
    (type: TerminalLine["type"], text: string) => {
      const id = lineIdRef.current++;
      setLines((prev) => [...prev, { id, type, text, timestamp: Date.now() }]);
    },
    []
  );

  const executeCommand = useCallback(
    async (cmd: string) => {
      if (!cmd.trim()) return;

      // Add to history
      setHistory((prev) => [...prev.filter((h) => h !== cmd), cmd]);
      setHistoryIndex(-1);

      // Show the command
      addLine("input", `${cwd}$ ${cmd}`);

      // Handle built-in commands
      if (cmd.trim() === "clear") {
        setLines([]);
        return;
      }

      if (cmd.trim().startsWith("cd ")) {
        const target = cmd.trim().slice(3).trim();
        // Resolve path
        let newPath: string;
        if (target === "~" || target === "") {
          newPath = "/home/ubuntu";
        } else if (target === "..") {
          newPath = cwd.split("/").slice(0, -1).join("/") || "/";
        } else if (target.startsWith("/")) {
          newPath = target;
        } else {
          newPath = `${cwd}/${target}`.replace(/\/+/g, "/");
        }
        setCwd(newPath);
        addLine("info", `Changed directory to ${newPath}`);
        return;
      }

      setIsRunning(true);

      try {
        const response = await fetch("/api/chat/slash", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            command: "/terminal",
            args: `${cwd} ${cmd}`,
          }),
        });

        const data = await response.json();
        if (data.result) {
          const outputLines = data.result.split("\n");
          for (const line of outputLines) {
            if (line.startsWith("STDERR:")) {
              addLine("error", line.replace("STDERR: ", ""));
            } else {
              addLine("output", line);
            }
          }
        }
        if (data.error) {
          addLine("error", data.error);
        }
      } catch (err: any) {
        addLine("error", `Network error: ${err.message}`);
      } finally {
        setIsRunning(false);
      }
    },
    [cwd, addLine]
  );

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === "Enter" && !isRunning) {
      executeCommand(input);
      setInput("");
    } else if (e.key === "ArrowUp") {
      e.preventDefault();
      if (history.length > 0) {
        const newIndex =
          historyIndex === -1 ? history.length - 1 : Math.max(0, historyIndex - 1);
        setHistoryIndex(newIndex);
        setInput(history[newIndex]);
      }
    } else if (e.key === "ArrowDown") {
      e.preventDefault();
      if (historyIndex >= 0) {
        const newIndex = historyIndex + 1;
        if (newIndex >= history.length) {
          setHistoryIndex(-1);
          setInput("");
        } else {
          setHistoryIndex(newIndex);
          setInput(history[newIndex]);
        }
      }
    } else if (e.key === "c" && e.ctrlKey) {
      if (isRunning) {
        addLine("error", "^C");
        setIsRunning(false);
      }
    }
  };

  const copyOutput = () => {
    const text = lines.map((l) => l.text).join("\n");
    navigator.clipboard.writeText(text);
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  };

  const clearTerminal = () => {
    setLines([
      {
        id: lineIdRef.current++,
        type: "info",
        text: "Terminal cleared.",
        timestamp: Date.now(),
      },
    ]);
  };

  if (!open) return null;

  return (
    <div
      className="fixed bottom-0 left-0 right-0 z-40 bg-background border-t border-border shadow-2xl"
      style={{ height: "40vh" }}
    >
      {/* Header */}
      <div className="flex items-center justify-between px-4 py-2 border-b border-border bg-secondary/30">
        <div className="flex items-center gap-2">
          <TerminalIcon className="size-4 text-green-400" />
          <span className="text-xs font-semibold">Terminal</span>
          <span className="text-[10px] text-muted-foreground font-mono">
            {cwd}
          </span>
        </div>
        <div className="flex items-center gap-1">
          <button
            onClick={copyOutput}
            className="size-6 rounded hover:bg-accent flex items-center justify-center text-muted-foreground hover:text-foreground"
            title="Copy output"
          >
            {copied ? <Check className="size-3.5" /> : <Copy className="size-3.5" />}
          </button>
          <button
            onClick={clearTerminal}
            className="size-6 rounded hover:bg-accent flex items-center justify-center text-muted-foreground hover:text-foreground"
            title="Clear"
          >
            <Trash2 className="size-3.5" />
          </button>
          <button
            onClick={onClose}
            className="size-6 rounded hover:bg-accent flex items-center justify-center text-muted-foreground hover:text-foreground"
          >
            <X className="size-4" />
          </button>
        </div>
      </div>

      {/* Terminal output */}
      <div
        ref={scrollRef}
        className="flex-1 overflow-y-auto p-3 font-mono text-xs leading-relaxed"
        style={{ height: "calc(40vh - 80px)" }}
        onClick={() => inputRef.current?.focus()}
      >
        {lines.map((line) => (
          <div
            key={line.id}
            className={cn(
              "whitespace-pre-wrap break-all",
              line.type === "input" && "text-green-400 font-bold",
              line.type === "output" && "text-foreground/80",
              line.type === "error" && "text-red-400",
              line.type === "info" && "text-cyan-400/70 italic"
            )}
          >
            {line.text}
          </div>
        ))}
      </div>

      {/* Input line */}
      <div className="flex items-center gap-2 px-3 py-2 border-t border-border bg-background">
        <span className="text-green-400 font-mono text-xs font-bold shrink-0">
          {cwd.replace("/home/ubuntu", "~")}$
        </span>
        <input
          ref={inputRef}
          value={input}
          onChange={(e) => setInput(e.target.value)}
          onKeyDown={handleKeyDown}
          disabled={isRunning}
          placeholder={isRunning ? "Running..." : "Type a command..."}
          className="flex-1 bg-transparent text-xs font-mono text-foreground outline-none placeholder:text-muted-foreground"
          autoFocus
        />
        {isRunning && (
          <Loader2 className="size-3.5 animate-spin text-primary shrink-0" />
        )}
      </div>
    </div>
  );
}
