import { html } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { createRef, ref } from "lit/directives/ref.js";
import { SketchTailwindElement } from "./sketch-tailwind-element";

@customElement("mobile-chat-input")
export class MobileChatInput extends SketchTailwindElement {
  @property({ type: Boolean })
  disabled = false;

  @state()
  private inputValue = "";

  @state()
  private uploadsInProgress = 0;

  @state()
  private showUploadProgress = false;

  private textareaRef = createRef<HTMLTextAreaElement>();

  private handleInput = (e: Event) => {
    const target = e.target as HTMLTextAreaElement;
    this.inputValue = target.value;
    this.adjustTextareaHeight();
  };

  private handlePaste = async (e: ClipboardEvent) => {
    // Check if the clipboard contains files
    if (e.clipboardData && e.clipboardData.files.length > 0) {
      const file = e.clipboardData.files[0];

      // Handle the file upload
      e.preventDefault(); // Prevent default paste behavior

      // Get the current cursor position
      const textarea = this.textareaRef.value;
      const cursorPos = textarea
        ? textarea.selectionStart
        : this.inputValue.length;
      await this.uploadFile(file, cursorPos);
    }
  };

  // Utility function to handle file uploads
  private async uploadFile(file: File, insertPosition: number) {
    // Insert a placeholder at the cursor position
    const textBefore = this.inputValue.substring(0, insertPosition);
    const textAfter = this.inputValue.substring(insertPosition);

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

    // Increment uploads in progress counter
    this.uploadsInProgress++;
    this.showUploadProgress = true;

    // Adjust spacing immediately to show loading indicator
    this.adjustTextareaHeight();

    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.inputValue = this.inputValue.replace(loadingText, `[${data.path}]`);

      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.inputValue = this.inputValue.replace(loadingText, errorText);

      throw error;
    } finally {
      // Always decrement the counter, even if there was an error
      this.uploadsInProgress--;
      if (this.uploadsInProgress === 0) {
        this.showUploadProgress = false;
      }
      this.adjustTextareaHeight();
      if (this.textareaRef.value) {
        this.textareaRef.value.focus();
      }
    }
  }

  private handleKeyDown = (e: KeyboardEvent) => {
    if (e.key === "Enter" && !e.shiftKey) {
      e.preventDefault();
      this.sendMessage();
    }
  };

  private adjustTextareaHeight() {
    if (this.textareaRef.value) {
      const textarea = this.textareaRef.value;
      textarea.style.height = "auto";
      textarea.style.height = Math.min(textarea.scrollHeight, 120) + "px";
    }
  }

  private sendMessage = () => {
    // Prevent sending if there are uploads in progress
    if (this.uploadsInProgress > 0) {
      console.log(
        `Message send prevented: ${this.uploadsInProgress} uploads in progress`,
      );
      return;
    }

    const message = this.inputValue.trim();
    if (message && !this.disabled) {
      this.dispatchEvent(
        new CustomEvent("send-message", {
          detail: { message },
          bubbles: true,
          composed: true,
        }),
      );

      this.inputValue = "";
      if (this.textareaRef.value) {
        this.textareaRef.value.value = "";
        this.adjustTextareaHeight();
        this.textareaRef.value.focus();
      }
    }
  };

  updated(changedProperties: Map<string, any>) {
    super.updated(changedProperties);
    this.adjustTextareaHeight();

    // Add paste event listener when component updates
    if (this.textareaRef.value && !this.textareaRef.value.onpaste) {
      this.textareaRef.value.addEventListener("paste", this.handlePaste);
    }
  }

  disconnectedCallback() {
    super.disconnectedCallback();
    // Clean up paste event listener
    if (this.textareaRef.value) {
      this.textareaRef.value.removeEventListener("paste", this.handlePaste);
    }
  }

  render() {
    const canSend =
      this.inputValue.trim().length > 0 &&
      !this.disabled &&
      this.uploadsInProgress === 0;

    return html`
      <div
        class="block bg-white border-t border-gray-200 p-3 relative z-[1000]"
        style="padding-bottom: max(12px, env(safe-area-inset-bottom)); padding-left: max(16px, env(safe-area-inset-left)); padding-right: max(16px, env(safe-area-inset-right));"
      >
        <div class="flex items-end gap-3 max-w-full">
          <div class="flex-1 relative min-w-0">
            <textarea
              ${ref(this.textareaRef)}
              .value=${this.inputValue}
              @input=${this.handleInput}
              @keydown=${this.handleKeyDown}
              placeholder="Message Sketch..."
              ?disabled=${this.disabled || this.uploadsInProgress > 0}
              rows="1"
              class="w-full min-h-[40px] max-h-[120px] p-3 border border-gray-300 rounded-[20px] text-base font-inherit leading-relaxed resize-none outline-none bg-gray-50 transition-colors duration-200 box-border focus:border-blue-500 focus:bg-white disabled:bg-gray-200 disabled:text-gray-500 disabled:cursor-not-allowed placeholder:text-gray-500"
              style="font-size: 16px;"
            ></textarea>

            ${this.showUploadProgress
              ? html`
                  <div
                    class="absolute -top-8 left-1/2 transform -translate-x-1/2 bg-yellow-50 text-yellow-800 px-2 py-1 rounded text-xs whitespace-nowrap shadow-sm z-[1000]"
                  >
                    Uploading ${this.uploadsInProgress}
                    file${this.uploadsInProgress > 1 ? "s" : ""}...
                  </div>
                `
              : ""}
          </div>

          <button
            class="flex-shrink-0 w-10 h-10 border-none rounded-full bg-blue-500 text-white cursor-pointer flex items-center justify-center text-lg transition-all duration-200 outline-none hover:bg-blue-600 active:scale-95 disabled:bg-gray-500 disabled:cursor-not-allowed disabled:opacity-60"
            @click=${this.sendMessage}
            ?disabled=${!canSend}
            title=${this.uploadsInProgress > 0
              ? "Please wait for upload to complete"
              : "Send message"}
          >
            ${this.uploadsInProgress > 0
              ? html`<span class="text-xs">⏳</span>`
              : html`<svg class="w-4 h-4 fill-current" viewBox="0 0 24 24">
                  <path d="M2,21L23,12L2,3V10L17,12L2,14V21Z" />
                </svg>`}
          </button>
        </div>
      </div>
    `;
  }
}
