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

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

  // 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 {
      position: fixed;
      bottom: 0;
      left: 0;
      width: 100%;
      background: #f0f0f0;
      padding: 15px;
      box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
      z-index: 1000;
      min-height: 40px; /* Ensure minimum height */
    }

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

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

  constructor() {
    super();

    // Binding methods
    this._handleUpdateContent = this._handleUpdateContent.bind(this);
  }

  /**
   * Handle update-content event
   */
  private _handleUpdateContent(event: CustomEvent) {
    const { content } = event.detail;
    if (content !== undefined) {
      this.content = content;

      // Update the textarea value directly, otherwise it won't update until next render
      const textarea = this.shadowRoot?.querySelector(
        "#chatInput",
      ) as HTMLTextAreaElement;
      if (textarea) {
        textarea.value = content;
        // Adjust height after content is updated programmatically
        requestAnimationFrame(() => this.adjustChatSpacing());
      }
    }
  }

  // See https://lit.dev/docs/components/lifecycle/
  connectedCallback() {
    super.connectedCallback();

    // Listen for update-content events
    this.addEventListener(
      "update-content",
      this._handleUpdateContent as EventListener,
    );
  }

  // See https://lit.dev/docs/components/lifecycle/
  disconnectedCallback() {
    super.disconnectedCallback();

    // Remove event listeners
    this.removeEventListener(
      "update-content",
      this._handleUpdateContent as EventListener,
    );
  }

  sendChatMessage() {
    const event = new CustomEvent("send-chat", {
      detail: { message: this.content },
      bubbles: true,
      composed: true,
    });
    this.dispatchEvent(event);
    this.content = ""; // Clear the input 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`;
  }

  _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();
    }
  }

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

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