import { Terminal } from "@xterm/xterm";
import { FitAddon } from "@xterm/addon-fit";

import { css, html, LitElement } from "lit";
import { customElement } from "lit/decorators.js";
import "./sketch-container-status";

@customElement("sketch-terminal")
export class SketchTerminal extends LitElement {
  // Terminal instance
  private terminal: Terminal | null = null;
  // Terminal fit addon for handling resize
  private fitAddon: FitAddon | null = null;
  // Flag to track if terminal has been fully initialized
  private isInitialized: boolean = false;
  // Terminal EventSource for SSE
  private terminalEventSource: EventSource | null = null;
  // Terminal ID (always 1 for now, will support 1-9 later)
  private terminalId: string = "1";
  // Queue for serializing terminal inputs
  private terminalInputQueue: string[] = [];
  // Flag to track if we're currently processing a terminal input
  private processingTerminalInput: boolean = false;

  static styles = css`
    /* Terminal View Styles */
    .terminal-view {
      width: 100%;
      background-color: #f5f5f5;
      border-radius: 8px;
      overflow: hidden;
      margin-bottom: 20px;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
      padding: 15px;
      height: 70vh;
    }

    .terminal-container {
      width: 100%;
      height: 100%;
      overflow: hidden;
    }
  `;

  constructor() {
    super();
    this._resizeHandler = this._resizeHandler.bind(this);
  }

  connectedCallback() {
    super.connectedCallback();
    this.loadXtermlCSS();
    // Setup resize handler
    window.addEventListener("resize", this._resizeHandler);
    // Listen for view mode changes to detect when terminal becomes visible
    window.addEventListener(
      "view-mode-select",
      this._handleViewModeSelect.bind(this),
    );
  }

  disconnectedCallback() {
    super.disconnectedCallback();

    window.removeEventListener("resize", this._resizeHandler);
    window.removeEventListener("view-mode-select", this._handleViewModeSelect);

    this.closeTerminalConnections();

    if (this.terminal) {
      this.terminal.dispose();
      this.terminal = null;
    }
    this.fitAddon = null;
  }

  firstUpdated() {
    // Do nothing - we'll initialize the terminal when it becomes visible
  }

  _resizeHandler() {
    // Only handle resize if terminal has been initialized
    if (this.fitAddon && this.isInitialized) {
      this.fitAddon.fit();
      // Send resize information to server
      this.sendTerminalResize();
    }
  }

  /**
   * Handle view mode selection event to detect when terminal becomes visible
   */
  private _handleViewModeSelect(event: CustomEvent) {
    const mode = event.detail.mode as "chat" | "diff" | "terminal";
    if (mode === "terminal") {
      // Terminal tab is now visible
      if (!this.isInitialized) {
        // First time the terminal is shown - initialize it
        this.isInitialized = true;
        setTimeout(() => this.initializeTerminal(), 10);
      } else if (this.fitAddon) {
        // Terminal already initialized - just resize it
        setTimeout(() => {
          this.fitAddon?.fit();
          this.sendTerminalResize();
          this.terminal?.focus();
        }, 10);
      }
    }
  }

  // Load xterm CSS into the shadow DOM
  private async loadXtermlCSS() {
    try {
      // Check if diff2html styles are already loaded
      const styleId = "xterm-styles";
      if (this.shadowRoot?.getElementById(styleId)) {
        return; // Already loaded
      }

      // Fetch the diff2html CSS
      const response = await fetch("static/xterm.css");

      if (!response.ok) {
        console.error(
          `Failed to load xterm CSS: ${response.status} ${response.statusText}`,
        );
        return;
      }

      const cssText = await response.text();

      // Create a style element and append to shadow DOM
      const style = document.createElement("style");
      style.id = styleId;
      style.textContent = cssText;
      this.renderRoot?.appendChild(style);

      console.log("xterm CSS loaded into shadow DOM");
    } catch (error) {
      console.error("Error loading xterm CSS:", error);
    }
  }

  /**
   * Initialize the terminal component
   * @param terminalContainer The DOM element to contain the terminal
   */
  public async initializeTerminal(): Promise<void> {
    const terminalContainer = this.renderRoot.querySelector(
      "#terminalContainer",
    ) as HTMLElement;

    if (!terminalContainer) {
      console.error("Terminal container not found");
      return;
    }

    // If terminal is already initialized, just focus it
    if (this.terminal) {
      this.terminal.focus();
      if (this.fitAddon) {
        this.fitAddon.fit();
      }
      return;
    }

    // Clear the terminal container
    terminalContainer.innerHTML = "";

    // Create new terminal instance
    this.terminal = new Terminal({
      cursorBlink: true,
      theme: {
        background: "#f5f5f5",
        foreground: "#333333",
        cursor: "#0078d7",
        selectionBackground: "rgba(0, 120, 215, 0.4)",
      },
    });

    // Add fit addon to handle terminal resizing
    this.fitAddon = new FitAddon();
    this.terminal.loadAddon(this.fitAddon);

    // Open the terminal in the container
    this.terminal.open(terminalContainer);

    // Connect to WebSocket
    await this.connectTerminal();

    // Fit the terminal to the container
    this.fitAddon.fit();

    // Focus the terminal
    this.terminal.focus();
  }

  /**
   * Connect to terminal events stream
   */
  private async connectTerminal(): Promise<void> {
    if (!this.terminal) {
      return;
    }

    // Close existing connections if any
    this.closeTerminalConnections();

    try {
      // Connect directly to the SSE endpoint for terminal 1
      // Use relative URL based on current location
      const baseUrl = window.location.pathname.endsWith("/") ? "." : ".";
      const eventsUrl = `${baseUrl}/terminal/events/${this.terminalId}`;
      this.terminalEventSource = new EventSource(eventsUrl);

      // Handle SSE events
      this.terminalEventSource.onopen = () => {
        console.log("Terminal SSE connection opened");
        this.sendTerminalResize();
      };

      this.terminalEventSource.onmessage = (event) => {
        if (this.terminal) {
          // Decode base64 data before writing to terminal
          try {
            // @ts-ignore This isn't in the type definitions yet; it's pretty new?!?
            const decoded = base64ToUint8Array(event.data);
            this.terminal.write(decoded);
          } catch (e) {
            console.error("Error decoding terminal data:", e);
          }
        }
      };

      this.terminalEventSource.onerror = (error) => {
        console.error("Terminal SSE error:", error);
        if (this.terminal) {
          this.terminal.write("\r\n\x1b[1;31mConnection error\x1b[0m\r\n");
        }
        // Attempt to reconnect if the connection was lost
        if (this.terminalEventSource?.readyState === EventSource.CLOSED) {
          this.closeTerminalConnections();
        }
      };

      // Send key inputs to the server via POST requests
      if (this.terminal) {
        this.terminal.onData((data) => {
          this.sendTerminalInput(data);
        });
      }
    } catch (error) {
      console.error("Failed to connect to terminal:", error);
      if (this.terminal) {
        this.terminal.write(
          `\r\n\x1b[1;31mFailed to connect: ${error}\x1b[0m\r\n`,
        );
      }
    }
  }

  /**
   * Close any active terminal connections
   */
  private closeTerminalConnections(): void {
    if (this.terminalEventSource) {
      this.terminalEventSource.close();
      this.terminalEventSource = null;
    }
  }

  /**
   * Send input to the terminal
   * @param data The input data to send
   */
  private async sendTerminalInput(data: string): Promise<void> {
    // Add the data to the queue
    this.terminalInputQueue.push(data);

    // If we're not already processing inputs, start processing
    if (!this.processingTerminalInput) {
      await this.processTerminalInputQueue();
    }
  }

  /**
   * Process the terminal input queue in order
   */
  private async processTerminalInputQueue(): Promise<void> {
    if (this.terminalInputQueue.length === 0) {
      this.processingTerminalInput = false;
      return;
    }

    this.processingTerminalInput = true;

    // Concatenate all available inputs from the queue into a single request
    let combinedData = "";

    // Take all currently available items from the queue
    while (this.terminalInputQueue.length > 0) {
      combinedData += this.terminalInputQueue.shift()!;
    }

    try {
      // Use relative URL based on current location
      const baseUrl = window.location.pathname.endsWith("/") ? "." : ".";
      const response = await fetch(
        `${baseUrl}/terminal/input/${this.terminalId}`,
        {
          method: "POST",
          body: combinedData,
          headers: {
            "Content-Type": "text/plain",
          },
        },
      );

      if (!response.ok) {
        console.error(
          `Failed to send terminal input: ${response.status} ${response.statusText}`,
        );
      }
    } catch (error) {
      console.error("Error sending terminal input:", error);
    }

    // Continue processing the queue (for any new items that may have been added)
    await this.processTerminalInputQueue();
  }

  /**
   * Send terminal resize information to the server
   */
  private async sendTerminalResize(): Promise<void> {
    if (!this.terminal || !this.fitAddon) {
      return;
    }

    // Get terminal dimensions
    try {
      // Send resize message in a format the server can understand
      // Use relative URL based on current location
      const baseUrl = window.location.pathname.endsWith("/") ? "." : ".";
      const response = await fetch(
        `${baseUrl}/terminal/input/${this.terminalId}`,
        {
          method: "POST",
          body: JSON.stringify({
            type: "resize",
            cols: this.terminal.cols || 80, // Default to 80 if undefined
            rows: this.terminal.rows || 24, // Default to 24 if undefined
          }),
          headers: {
            "Content-Type": "application/json",
          },
        },
      );

      if (!response.ok) {
        console.error(
          `Failed to send terminal resize: ${response.status} ${response.statusText}`,
        );
      }
    } catch (error) {
      console.error("Error sending terminal resize:", error);
    }
  }

  render() {
    return html`
      <div id="terminalView" class="terminal-view">
        <div id="terminalContainer" class="terminal-container"></div>
      </div>
    `;
  }
}

function base64ToUint8Array(base64String) {
  // This isn't yet available in Chrome, but Safari has it!
  // @ts-ignore
  if (Uint8Array.fromBase64) {
    // @ts-ignore
    return Uint8Array.fromBase64(base64String);
  }

  const binaryString = atob(base64String);
  return Uint8Array.from(binaryString, (char) => char.charCodeAt(0));
}

declare global {
  interface HTMLElementTagNameMap {
    "sketch-terminal": SketchTerminal;
  }
}
