import { Component, Prop, Event, EventEmitter, State, Method, h } from '@stencil/core';

interface ImagePreview {
  id: string;
  file: File;
  dataUrl: string;
}

@Component({
  tag: 'bcx-message-composer',
  styleUrl: 'bcx-message-composer.scss',
  shadow: true,
})
export class BcxMessageComposer {
  @Prop() disabled: boolean = false;
  @Prop() loading: boolean = false;
  @Prop() placeholder: string = 'Type your message...';
  @Prop() maxLength: number = 1000;
  @Prop() theme: 'light' | 'dark' = 'light';
  @Prop() isAttachmentsDisabled: boolean = false;

  @State() message: string = '';
  @State() images: ImagePreview[] = [];

  @Event() messageSubmit: EventEmitter<{ content: string; images: File[] }>;
  @Event() attachmentsChange: EventEmitter<{ count: number }>;

  private textareaRef: HTMLTextAreaElement;
  private fileInputRef: HTMLInputElement;

  private emitAttachmentsCount() {
    this.attachmentsChange.emit({ count: this.images.length });
  }

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

  private handleKeyDown = (event: KeyboardEvent) => {
    if (event.key === 'Enter' && !event.shiftKey) {
      event.preventDefault();
      this.submitMessage();
    }
  };

  private handleSubmit = (event: Event) => {
    event.preventDefault();
    this.submitMessage();
  };

  @Method()
  async clearAttachments(): Promise<void> {
    this.images = [];
    this.emitAttachmentsCount();
  }

  private submitMessage() {
    const trimmedMessage = this.message.trim();
    if (!this.disabled && trimmedMessage) {
      this.messageSubmit.emit({
        content: trimmedMessage,
        images: this.images.map(img => img.file),
      });
      this.message = '';
      this.images = [];
      this.emitAttachmentsCount();
      this.adjustTextareaHeight();
    }
  }

  private handleImageUpload = (event: Event) => {
    if (this.isAttachmentsDisabled) {
      return;
    }

    const target = event.target as HTMLInputElement;
    const files = target.files;

    if (files && files.length > 0) {
      const maxImages = 3;
      const remainingSlots = maxImages - this.images.length;

      for (let i = 0; i < Math.min(files.length, remainingSlots); i++) {
        const file = files[i];

        const allowedFormats = ['png', 'jpg', 'jpeg', 'gif', 'webp'];
        const fileExtension = file.name.split('.').pop()?.toLowerCase();
        const mimeType = file.type.toLowerCase();

        const isValidFormat = allowedFormats.some(format => fileExtension === format || mimeType === `image/${format}`);

        if (!isValidFormat) {
          console.warn(`File ${file.name} is not a supported image format. Allowed: ${allowedFormats.join(', ')}`);
          continue;
        }

        if (file.size > 5 * 1024 * 1024) {
          console.warn(`File ${file.name} is too large (max 5MB)`);
          continue;
        }

        const reader = new FileReader();
        reader.onload = e => {
          const dataUrl = e.target?.result as string;
          const imagePreview: ImagePreview = {
            id: Math.random().toString(36).substr(2, 9),
            file,
            dataUrl,
          };

          this.images = [...this.images, imagePreview];
          // Notify parent after Stencil applies image state (avoids parent re-render racing preview paint).
          queueMicrotask(() => this.emitAttachmentsCount());
        };
        reader.onerror = () => {
          console.warn('[bcx-message-composer] Failed to read image file for preview');
        };
        reader.readAsDataURL(file);
      }
    }

    target.value = '';
  };

  private removeImage = (imageId: string) => {
    this.images = this.images.filter(img => img.id !== imageId);
    this.emitAttachmentsCount();
  };

  private triggerImageUpload = () => {
    if (this.disabled || this.loading || this.images.length >= 3 || this.isAttachmentsDisabled) {
      return;
    }

    this.fileInputRef?.click();
  };

  private adjustTextareaHeight() {
    if (this.textareaRef) {
      this.textareaRef.style.height = 'auto';
      this.textareaRef.style.height = Math.min(this.textareaRef.scrollHeight, 160) + 'px';
    }
  }

  render() {
    const isSubmitDisabled = !this.message.trim() || this.disabled || this.loading;
    const canUploadMoreImages = !this.disabled && !this.loading && this.images.length < 3 && !this.isAttachmentsDisabled;
    const actionsClass = this.isAttachmentsDisabled ? 'bcx-composer__actions bcx-composer__actions--no-attachments' : 'bcx-composer__actions';

    return (
      <form class={`bcx-composer ${this.theme === 'dark' ? 'dark' : ''}`} onSubmit={this.handleSubmit} data-adblock-bypass="true" role="form" aria-label="Message composer">
        {!this.isAttachmentsDisabled && (
          <input
            ref={el => (this.fileInputRef = el)}
            type="file"
            accept="image/png,image/jpg,image/jpeg,image/gif,image/webp"
            multiple
            onChange={this.handleImageUpload}
            style={{ display: 'none' }}
            data-adblock-bypass="true"
          />
        )}

        {this.images.length > 0 && (
          <div class="bcx-composer__image-previews" data-adblock-bypass="true" aria-label="Image previews">
            {this.images.map(image => (
              <div key={image.id} class="bcx-composer__image-preview" data-adblock-bypass="true">
                <img src={image.dataUrl} alt="Preview" class="bcx-composer__image-preview-img" data-adblock-bypass="true" />
                <button type="button" class="bcx-composer__image-remove" onClick={() => this.removeImage(image.id)} aria-label="Remove image" data-adblock-bypass="true">
                  <svg
                    width="16"
                    height="16"
                    viewBox="0 0 24 24"
                    fill="none"
                    stroke="currentColor"
                    stroke-width="2"
                    stroke-linecap="round"
                    stroke-linejoin="round"
                    aria-hidden="true"
                  >
                    <line x1="18" y1="6" x2="6" y2="18"></line>
                    <line x1="6" y1="6" x2="18" y2="18"></line>
                  </svg>
                </button>
              </div>
            ))}
          </div>
        )}

        <div class="bcx-composer__field">
          <textarea
            ref={el => (this.textareaRef = el)}
            class="bcx-composer__input"
            value={this.message}
            onInput={this.handleInput}
            onKeyDown={this.handleKeyDown}
            placeholder={this.placeholder}
            disabled={this.disabled}
            maxlength={this.maxLength}
            rows={1}
            aria-label="Type your message"
            data-adblock-bypass="true"
          />
          <div class={actionsClass}>
            {!this.isAttachmentsDisabled && (
              <button
                type="button"
                class="bcx-composer__media-btn"
                onClick={this.triggerImageUpload}
                disabled={!canUploadMoreImages}
                aria-label="Add image"
                data-adblock-bypass="true"
              >
                <svg
                  width="18"
                  height="18"
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                  stroke-width="2"
                  stroke-linecap="round"
                  stroke-linejoin="round"
                  aria-hidden="true"
                >
                  <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
                  <circle cx="8.5" cy="8.5" r="1.5"></circle>
                  <polyline points="21,15 16,10 5,21"></polyline>
                </svg>
              </button>
            )}

            <button
              type="submit"
              class="bcx-composer__submit"
              disabled={isSubmitDisabled}
              aria-label="Send message"
              data-loading={this.loading.toString()}
              data-adblock-bypass="true"
            >
              <span class="bcx-composer__submit-icon" aria-hidden="true">
                {this.loading ? (
                  <svg
                    class="bcx-composer__spinner"
                    width="18"
                    height="18"
                    viewBox="0 0 24 24"
                    fill="none"
                    stroke="currentColor"
                    stroke-width="2"
                    stroke-linecap="round"
                    stroke-linejoin="round"
                  >
                    <line x1="12" y1="2" x2="12" y2="6"></line>
                    <line x1="12" y1="18" x2="12" y2="22"></line>
                    <line x1="4.93" y1="4.93" x2="7.76" y2="7.76"></line>
                    <line x1="16.24" y1="16.24" x2="19.07" y2="19.07"></line>
                    <line x1="2" y1="12" x2="6" y2="12"></line>
                    <line x1="18" y1="12" x2="22" y2="12"></line>
                    <line x1="4.93" y1="19.07" x2="7.76" y2="16.24"></line>
                    <line x1="16.24" y1="7.76" x2="19.07" y2="4.93"></line>
                  </svg>
                ) : (
                  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <line x1="22" y1="2" x2="11" y2="13"></line>
                    <polygon points="22,2 15,22 11,13 2,9 22,2"></polygon>
                  </svg>
                )}
              </span>
            </button>
          </div>
        </div>
      </form>
    );
  }
}
