"use client";

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

interface InteractiveTerminalProps {
  repoUrl?: string;
}

export default function InteractiveTerminal({ repoUrl }: InteractiveTerminalProps) {
  const terminalRef = useRef<HTMLDivElement>(null);
  const terminalInstance = useRef<Terminal | null>(null);
  const fitAddon = useRef<FitAddon | null>(null);
  const ws = useRef<WebSocket | null>(null);
  const [isConnected, setIsConnected] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [reconnectKey, setReconnectKey] = useState(0);

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

    // Initialize xterm
    const term = new Terminal({
      cursorBlink: true,
      theme: {
        background: "#1e1e1e",
        foreground: "#d4d4d4",
      },
      fontFamily: 'Menlo, Monaco, "Courier New", monospace',
      fontSize: 14,
    });
    
    const fit = new FitAddon();
    term.loadAddon(fit);
    
    term.open(terminalRef.current);
    fit.fit();

    terminalInstance.current = term;
    fitAddon.current = fit;

    // Build the WebSocket URL
    let backendUrl = "http://localhost:8000";
    if (process.env.NEXT_PUBLIC_BACKEND_URL) {
      backendUrl = process.env.NEXT_PUBLIC_BACKEND_URL.replace(/\/$/, "");
    } else if (typeof window !== "undefined") {
      const port = window.location.port;
      const hostname = window.location.hostname;
      if (port === "3000") {
        backendUrl = `${window.location.protocol}//${hostname}:8000`;
      } else {
        backendUrl = `${window.location.protocol}//${window.location.host}`;
      }
    }
    
    const protocol = backendUrl.startsWith("https") ? "wss:" : "ws:";
    const host = backendUrl.replace(/^https?:\/\//, "");
    
    let wsUrl = `${protocol}//${host}/api/terminal/ws`;
    if (repoUrl) {
      wsUrl += `?repo_url=${encodeURIComponent(repoUrl)}`;
    }

    const socket = new WebSocket(wsUrl);
    ws.current = socket;

    socket.onopen = () => {
      setIsConnected(true);
      setError(null);
      
      // Initial resize
      if (terminalInstance.current) {
        const { cols, rows } = terminalInstance.current;
        socket.send(JSON.stringify({ type: "resize", cols, rows }));
      }
    };

    socket.onmessage = (event) => {
      if (typeof event.data === "string") {
        term.write(event.data);
      }
    };

    socket.onerror = () => {
      setError("WebSocket connection error");
      setIsConnected(false);
    };

    socket.onclose = () => {
      setIsConnected(false);
      setError("Disconnected");
      term.write("\r\n\x1b[31m[Process Exited / Connection Closed]\x1b[0m\r\n");
    };

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

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

    window.addEventListener("resize", handleResize);

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

  return (
    <div className="flex flex-col h-full w-full bg-[#1e1e1e] border-l border-zinc-800">
      <div className="flex items-center justify-between px-4 py-2 bg-zinc-900 border-b border-zinc-800 text-xs text-zinc-400">
        <div className="flex items-center gap-2">
          <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" /></svg>
          <span className="uppercase font-semibold tracking-wider">Terminal</span>
        </div>
        <div className="flex items-center gap-2">
          {isConnected ? (
            <span className="flex items-center gap-1.5"><span className="w-2 h-2 rounded-full bg-green-500 animate-pulse"></span> Connected</span>
          ) : error ? (
            <>
              <span className="flex items-center gap-1.5 text-red-400"><span className="w-2 h-2 rounded-full bg-red-500"></span> Disconnected</span>
              <button onClick={() => setReconnectKey(k => k + 1)} className="ml-2 px-2 py-0.5 bg-zinc-800 hover:bg-zinc-700 text-zinc-300 rounded transition-colors border border-zinc-700">Reconnect</button>
            </>
          ) : (
            <span className="flex items-center gap-1.5"><span className="w-2 h-2 rounded-full bg-zinc-500"></span> Connecting...</span>
          )}
        </div>
      </div>
      <div className="flex-1 overflow-hidden p-2" ref={terminalRef}></div>
    </div>
  );
}
