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;
  // 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);
  }

  disconnectedCallback() {
    super.disconnectedCallback();

    window.removeEventListener("resize", this._resizeHandler);

    this.closeTerminalConnections();

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

  firstUpdated() {
    this.initializeTerminal();
  }

  _resizeHandler() {
    if (this.fitAddon) {
      this.fitAddon.fit();
      // Send resize information to server
      this.sendTerminalResize();
    }
  }

  // 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;
  }
}
