import { css, html, LitElement, PropertyValues } from "lit";
import { customElement, property, state, query } from "lit/decorators.js";

@customElement("sketch-chat-input")
export class SketchChatInput extends LitElement {
  @state()
  content: string = "";

  @state()
  isDraggingOver: boolean = false;

  // See https://lit.dev/docs/components/styles/ for how lit-element handles CSS.
  // Note that these styles only apply to the scope of this web component's
  // shadow DOM node, so they won't leak out or collide with CSS declared in
  // other components or the containing web page (...unless you want it to do that).
  static styles = css`
    /* Chat styles - exactly matching timeline.css */
    .chat-container {
      width: 100%;
      background: #f0f0f0;
      padding: 15px;
      min-height: 40px; /* Ensure minimum height */
      position: relative;
    }

    .chat-input-wrapper {
      display: flex;
      max-width: 1200px;
      margin: 0 auto;
      gap: 10px;
    }

    #chatInput {
      flex: 1;
      padding: 12px;
      border: 1px solid #ddd;
      border-radius: 4px;
      resize: vertical;
      font-family: monospace;
      font-size: 12px;
      min-height: 40px;
      max-height: 300px;
      background: #f7f7f7;
      overflow-y: auto;
      box-sizing: border-box; /* Ensure padding is included in height calculation */
      line-height: 1.4; /* Consistent line height for better height calculation */
    }

    #sendChatButton {
      background-color: #2196f3;
      color: white;
      border: none;
      border-radius: 4px;
      padding: 0 20px;
      cursor: pointer;
      font-weight: 600;
      align-self: center;
      height: 40px;
    }

    #sendChatButton:hover {
      background-color: #0d8bf2;
    }

    /* Drop zone styling */
    .drop-zone-overlay {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: rgba(33, 150, 243, 0.1);
      border: 2px dashed #2196f3;
      border-radius: 4px;
      display: flex;
      justify-content: center;
      align-items: center;
      z-index: 10;
      pointer-events: none;
    }

    .drop-zone-message {
      background-color: #ffffff;
      padding: 15px 20px;
      border-radius: 4px;
      font-weight: 600;
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
    }
  `;

  constructor() {
    super();
    this._handleDiffComment = this._handleDiffComment.bind(this);
    this._handleDragOver = this._handleDragOver.bind(this);
    this._handleDragEnter = this._handleDragEnter.bind(this);
    this._handleDragLeave = this._handleDragLeave.bind(this);
    this._handleDrop = this._handleDrop.bind(this);
  }

  connectedCallback() {
    super.connectedCallback();
    window.addEventListener("diff-comment", this._handleDiffComment);
  }

  // Utility function to handle file uploads (used by both paste and drop handlers)
  private async _uploadFile(file: File, insertPosition: number) {
    // Insert a placeholder at the cursor position
    const textBefore = this.content.substring(0, insertPosition);
    const textAfter = this.content.substring(insertPosition);

    // Add a loading indicator
    const loadingText = `[Uploading ${file.name}...]`;
    this.content = `${textBefore}${loadingText}${textAfter}`;

    // Adjust spacing immediately to show loading indicator
    requestAnimationFrame(() => this.adjustChatSpacing());

    try {
      // Create a FormData object to send the file
      const formData = new FormData();
      formData.append("file", file);

      // Upload the file to the server using a relative path
      const response = await fetch("./upload", {
        method: "POST",
        body: formData,
      });

      if (!response.ok) {
        throw new Error(`Upload failed: ${response.statusText}`);
      }

      const data = await response.json();

      // Replace the loading placeholder with the actual file path
      this.content = this.content.replace(loadingText, `[${data.path}]`);

      // Adjust the cursor position after the inserted text
      requestAnimationFrame(() => {
        this.adjustChatSpacing();
        this.chatInput.focus();
        const newPos = textBefore.length + data.path.length + 2; // +2 for the brackets
        this.chatInput.selectionStart = newPos;
        this.chatInput.selectionEnd = newPos;
      });

      return data.path;
    } catch (error) {
      console.error("Failed to upload file:", error);

      // Replace loading indicator with error message
      const errorText = `[Upload failed: ${error.message}]`;
      this.content = this.content.replace(loadingText, errorText);

      // Adjust spacing to show error message
      requestAnimationFrame(() => {
        this.adjustChatSpacing();
        this.chatInput.focus();
      });

      throw error;
    }
  }

  // Handle paste events for files (including images)
  private _handlePaste = async (event: ClipboardEvent) => {
    // Check if the clipboard contains files
    if (event.clipboardData && event.clipboardData.files.length > 0) {
      const file = event.clipboardData.files[0];

      // Handle the file upload (for any file type, not just images)
      event.preventDefault(); // Prevent default paste behavior

      // Get the current cursor position
      const cursorPos = this.chatInput.selectionStart;
      await this._uploadFile(file, cursorPos);
    }
  };

  // Handle drag events for file drop operation
  private _handleDragOver(event: DragEvent) {
    event.preventDefault(); // Necessary to allow dropping
    event.stopPropagation();
  }

  private _handleDragEnter(event: DragEvent) {
    event.preventDefault();
    event.stopPropagation();
    this.isDraggingOver = true;
  }

  private _handleDragLeave(event: DragEvent) {
    event.preventDefault();
    event.stopPropagation();
    // Only set to false if we're leaving the container (not entering a child element)
    if (event.target === this.renderRoot.querySelector(".chat-container")) {
      this.isDraggingOver = false;
    }
  }

  private _handleDrop = async (event: DragEvent) => {
    event.preventDefault();
    event.stopPropagation();
    this.isDraggingOver = false;

    // Check if the dataTransfer contains files
    if (event.dataTransfer && event.dataTransfer.files.length > 0) {
      // Process all dropped files
      for (let i = 0; i < event.dataTransfer.files.length; i++) {
        const file = event.dataTransfer.files[i];
        try {
          // For the first file, insert at the cursor position
          // For subsequent files, append at the end of the content
          const insertPosition =
            i === 0 ? this.chatInput.selectionStart : this.content.length;
          await this._uploadFile(file, insertPosition);

          // Add a space between multiple files
          if (i < event.dataTransfer.files.length - 1) {
            this.content += " ";
          }
        } catch (error) {
          // Error already handled in _uploadFile
          console.error("Failed to process dropped file:", error);
          // Continue with the next file
        }
      }
    }
  };

  private _handleDiffComment(event: CustomEvent) {
    const { comment } = event.detail;
    if (!comment) return;

    if (this.content != "") {
      this.content += "\n\n";
    }
    this.content += comment;
    requestAnimationFrame(() => this.adjustChatSpacing());
  }

  // See https://lit.dev/docs/components/lifecycle/
  disconnectedCallback() {
    super.disconnectedCallback();
    window.removeEventListener("diff-comment", this._handleDiffComment);

    // Clean up drag and drop event listeners
    const container = this.renderRoot.querySelector(".chat-container");
    if (container) {
      container.removeEventListener("dragover", this._handleDragOver);
      container.removeEventListener("dragenter", this._handleDragEnter);
      container.removeEventListener("dragleave", this._handleDragLeave);
      container.removeEventListener("drop", this._handleDrop);
    }

    // Clean up paste event listener
    if (this.chatInput) {
      this.chatInput.removeEventListener("paste", this._handlePaste);
    }
  }

  sendChatMessage() {
    const event = new CustomEvent("send-chat", {
      detail: { message: this.content },
      bubbles: true,
      composed: true,
    });
    this.dispatchEvent(event);

    // TODO(philip?): Ideally we only clear the content if the send is successful.
    this.content = ""; // Clear content after sending
  }

  adjustChatSpacing() {
    if (!this.chatInput) return;

    // Reset height to minimal value to correctly calculate scrollHeight
    this.chatInput.style.height = "auto";

    // Get the scroll height (content height)
    const scrollHeight = this.chatInput.scrollHeight;

    // Set the height to match content (up to max-height which is handled by CSS)
    this.chatInput.style.height = `${scrollHeight}px`;
  }

  async _sendChatClicked() {
    this.sendChatMessage();
    this.chatInput.focus(); // Refocus the input after sending
    // Reset height after sending a message
    requestAnimationFrame(() => this.adjustChatSpacing());
  }

  _chatInputKeyDown(event: KeyboardEvent) {
    // Send message if Enter is pressed without Shift key
    if (event.key === "Enter" && !event.shiftKey) {
      event.preventDefault(); // Prevent default newline
      this.sendChatMessage();
    }
  }

  _chatInputChanged(event) {
    this.content = event.target.value;
    // Use requestAnimationFrame to ensure DOM updates have completed
    requestAnimationFrame(() => this.adjustChatSpacing());
  }

  @query("#chatInput")
  chatInput: HTMLTextAreaElement;

  protected firstUpdated(): void {
    if (this.chatInput) {
      this.chatInput.focus();
      // Initialize the input height
      this.adjustChatSpacing();

      // Add paste event listener for image handling
      this.chatInput.addEventListener("paste", this._handlePaste);

      // Add drag and drop event listeners
      const container = this.renderRoot.querySelector(".chat-container");
      if (container) {
        container.addEventListener("dragover", this._handleDragOver);
        container.addEventListener("dragenter", this._handleDragEnter);
        container.addEventListener("dragleave", this._handleDragLeave);
        container.addEventListener("drop", this._handleDrop);
      }
    }

    // Add window.onload handler to ensure the input is focused when the page fully loads
    window.addEventListener(
      "load",
      () => {
        if (this.chatInput) {
          this.chatInput.focus();
        }
      },
      { once: true },
    );
  }

  render() {
    return html`
      <div class="chat-container">
        <div class="chat-input-wrapper">
          <textarea
            id="chatInput"
            placeholder="Type your message here and press Enter to send..."
            autofocus
            @keydown="${this._chatInputKeyDown}"
            @input="${this._chatInputChanged}"
            .value=${this.content || ""}
          ></textarea>
          <button @click="${this._sendChatClicked}" id="sendChatButton">
            Send
          </button>
        </div>
        ${this.isDraggingOver
          ? html`
              <div class="drop-zone-overlay">
                <div class="drop-zone-message">Drop files here</div>
              </div>
            `
          : ""}
      </div>
    `;
  }
}

declare global {
  interface HTMLElementTagNameMap {
    "sketch-chat-input": SketchChatInput;
  }
}
