import React, { useEffect, useRef, useState } from "react";
import { Terminal } from "xterm";
import { FitAddon } from "xterm-addon-fit";
import { WebLinksAddon } from "xterm-addon-web-links";
import "xterm/css/xterm.css";

interface TerminalProps {
  instanceId: string;
  onClose?: () => void;
}

export const TerminalComponent: React.FC<TerminalProps> = ({ instanceId, onClose }) => {
  const terminalRef = useRef<HTMLDivElement>(null);
  const wsRef = useRef<WebSocket | null>(null);
  const [status, setStatus] = useState<"connecting" | "connected" | "disconnected" | "error">(
    "connecting",
  );
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    if (!terminalRef.current) return;

    // Initialize terminal
    const term = new Terminal({
      cursorBlink: true,
      fontSize: 14,
      fontFamily: 'Menlo, Monaco, "Courier New", monospace',
      theme: {
        background: "#1e1e1e",
        foreground: "#d4d4d4",
        cursor: "#d4d4d4",
        selectionBackground: "#264f78",
        black: "#000000",
        red: "#cd3131",
        green: "#0dbc79",
        yellow: "#e5e510",
        blue: "#2472c8",
        magenta: "#bc3fbc",
        cyan: "#11a8cd",
        white: "#e5e5e5",
        brightBlack: "#666666",
        brightRed: "#f14c4c",
        brightGreen: "#23d18b",
        brightYellow: "#f5f543",
        brightBlue: "#3b8eea",
        brightMagenta: "#d670d6",
        brightCyan: "#29b8db",
        brightWhite: "#e5e5e5",
      },
    });

    const fitAddon = new FitAddon();
    term.loadAddon(fitAddon);
    term.loadAddon(new WebLinksAddon());

    term.open(terminalRef.current);
    fitAddon.fit();

    // Build WebSocket URL
    const apiUrl = import.meta.env.VITE_API_BASE_URL || "";
    const wsProtocol = window.location.protocol === "https:" ? "wss:" : "ws:";
    const wsHost = apiUrl.replace(/^https?:\/\//, "").replace(/\/+$/, "");
    const wsUrl = `${wsProtocol}//${wsHost}/ws/tool-instances/${instanceId}/terminal`;

    // Connect WebSocket
    const ws = new WebSocket(wsUrl);
    wsRef.current = ws;

    ws.onopen = () => {
      setStatus("connected");
      setError(null);
    };

    ws.onmessage = (event) => {
      if (event.data instanceof Blob) {
        event.data.arrayBuffer().then((buffer) => {
          const data = new Uint8Array(buffer);
          term.write(data);
        });
      } else if (typeof event.data === "string") {
        try {
          const msg = JSON.parse(event.data);
          if (msg.type === "status" && msg.status === "connected") {
            setStatus("connected");
          }
        } catch {
          term.write(event.data);
        }
      }
    };

    ws.onclose = (event) => {
      setStatus("disconnected");
      if (event.code !== 1000) {
        setError(`Connection closed (code: ${event.code})`);
      }
    };

    ws.onerror = () => {
      setStatus("error");
      setError("WebSocket error");
    };

    // Handle terminal input
    term.onData((data) => {
      if (ws.readyState === WebSocket.OPEN) {
        ws.send(data);
      }
    });

    // Handle resize
    const handleResize = () => {
      fitAddon.fit();
      const { cols, rows } = term;
      if (ws.readyState === WebSocket.OPEN) {
        ws.send(
          JSON.stringify({
            type: "resize",
            cols,
            rows,
          }),
        );
      }
    };

    window.addEventListener("resize", handleResize);

    // Initial resize
    setTimeout(handleResize, 100);

    return () => {
      window.removeEventListener("resize", handleResize);
      ws.close();
      term.dispose();
    };
  }, [instanceId]);

  return (
    <div className="terminal-wrapper">
      <div className="terminal-header">
        <div className="terminal-status">
          <span
            className={`status-dot ${status}`}
            aria-label={`Terminal status: ${status}`}
          />
          <span className="status-text">{status}</span>
        </div>
        {onClose && (
          <button className="terminal-close" onClick={onClose} type="button">
            Close
          </button>
        )}
      </div>
      {error && <div className="terminal-error">{error}</div>}
      <div ref={terminalRef} className="terminal-container" />
    </div>
  );
};
