import {
  customElement,
  html,
  css,
  cssManager,
  property,
  state,
  type TemplateResult,
} from '@design.estate/dees-element';
import { DeesInputBase } from '../dees-input-base/dees-input-base.js';
import '../../dees-icon/dees-icon.js';
import '../../00group-button/dees-button/dees-button.js';
import { demoFunc } from './dees-input-list.demo.js';
import { themeDefaultStyles } from '../../00theme.js';

declare global {
  interface HTMLElementTagNameMap {
    'dees-input-list': DeesInputList;
  }
}

@customElement('dees-input-list')
export class DeesInputList extends DeesInputBase<DeesInputList> {
  // STATIC
  public static demo = demoFunc;

  // INSTANCE
  @property({ type: Array })
  accessor value: string[] = [];

  @property({ type: String })
  accessor placeholder: string = 'Add new item...';

  @property({ type: Number })
  accessor maxItems: number = 0; // 0 means unlimited

  @property({ type: Number })
  accessor minItems: number = 0;

  @property({ type: Boolean })
  accessor allowDuplicates: boolean = false;

  @property({ type: Boolean })
  accessor sortable: boolean = false;

  @property({ type: Boolean })
  accessor confirmDelete: boolean = false;

  @property({ type: String })
  accessor validationText: string = '';

  @state()
  accessor inputValue: string = '';

  @state()
  accessor editingIndex: number = -1;

  @state()
  accessor editingValue: string = '';

  @state()
  accessor draggedIndex: number = -1;

  @state()
  accessor dragOverIndex: number = -1;

  public static styles = [
    themeDefaultStyles,
    ...DeesInputBase.baseStyles,
    cssManager.defaultStyles,
    css`
      /* TODO: Migrate hardcoded values to --dees-* CSS variables */
      :host {
        display: block;
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
      }

      .input-wrapper {
        width: 100%;
      }

      .list-container {
        background: ${cssManager.bdTheme('hsl(0 0% 100%)', 'hsl(0 0% 3.9%)')};
        border: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')};
        border-radius: 6px;
        overflow: hidden;
        transition: all 0.15s ease;
      }

      .list-container:hover:not(.disabled) {
        border-color: ${cssManager.bdTheme('hsl(0 0% 79.8%)', 'hsl(0 0% 20.9%)')};
      }

      .list-container:focus-within {
        border-color: ${cssManager.bdTheme('hsl(222.2 47.4% 51.2%)', 'hsl(217.2 91.2% 59.8%)')};
        box-shadow: 0 0 0 3px ${cssManager.bdTheme('hsl(222.2 47.4% 51.2% / 0.1)', 'hsl(217.2 91.2% 59.8% / 0.1)')};
      }

      .list-container.disabled {
        opacity: 0.6;
        cursor: not-allowed;
      }

      .list-items {
        max-height: 400px;
        overflow-y: auto;
      }

      .list-item {
        display: flex;
        align-items: center;
        gap: 8px;
        padding: 12px 16px;
        border-bottom: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')};
        background: ${cssManager.bdTheme('hsl(0 0% 100%)', 'hsl(0 0% 3.9%)')};
        transition: all 0.15s ease;
        position: relative;
        overflow: hidden; /* Prevent animation from affecting scroll bounds */
      }

      .list-item:last-of-type {
        border-bottom: none;
      }

      .list-item:hover:not(.disabled) {
        background: ${cssManager.bdTheme('hsl(0 0% 97.5%)', 'hsl(0 0% 6.9%)')};
      }

      .list-item.dragging {
        opacity: 0.4;
        background: ${cssManager.bdTheme('hsl(210 40% 96.1%)', 'hsl(215 20.2% 10.8%)')};
      }

      .list-item.drag-over {
        background: ${cssManager.bdTheme('hsl(210 40% 93.1%)', 'hsl(215 20.2% 13.8%)')};
        border-color: ${cssManager.bdTheme('hsl(222.2 47.4% 51.2%)', 'hsl(217.2 91.2% 59.8%)')};
      }

      .drag-handle {
        display: flex;
        align-items: center;
        cursor: move;
        color: ${cssManager.bdTheme('hsl(0 0% 63.9%)', 'hsl(0 0% 45.1%)')};
        transition: color 0.15s ease;
      }

      .drag-handle:hover {
        color: ${cssManager.bdTheme('hsl(0 0% 45.1%)', 'hsl(0 0% 63.9%)')};
      }

      .drag-handle dees-icon {
        width: 16px;
        height: 16px;
      }

      .item-content {
        flex: 1;
        display: flex;
        align-items: center;
        min-width: 0;
      }

      .item-text {
        flex: 1;
        color: ${cssManager.bdTheme('hsl(0 0% 9%)', 'hsl(0 0% 95%)')};
        font-size: 14px;
        line-height: 20px;
        word-break: break-word;
      }

      .item-edit-input {
        flex: 1;
        padding: 4px 8px;
        font-size: 14px;
        font-family: inherit;
        background: ${cssManager.bdTheme('hsl(0 0% 100%)', 'hsl(0 0% 9%)')};
        border: 1px solid ${cssManager.bdTheme('hsl(222.2 47.4% 51.2%)', 'hsl(217.2 91.2% 59.8%)')};
        border-radius: 4px;
        outline: none;
        color: ${cssManager.bdTheme('hsl(0 0% 9%)', 'hsl(0 0% 95%)')};
      }

      .item-actions {
        display: flex;
        gap: 4px;
        align-items: center;
      }

      .action-button {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 28px;
        height: 28px;
        border-radius: 4px;
        background: transparent;
        border: none;
        cursor: pointer;
        transition: all 0.15s ease;
        color: ${cssManager.bdTheme('hsl(0 0% 45.1%)', 'hsl(0 0% 63.9%)')};
      }

      .action-button:hover {
        background: ${cssManager.bdTheme('hsl(0 0% 95.1%)', 'hsl(0 0% 14.9%)')};
        color: ${cssManager.bdTheme('hsl(0 0% 9%)', 'hsl(0 0% 95%)')};
      }

      .action-button.save {
        color: ${cssManager.bdTheme('hsl(142.1 76.2% 36.3%)', 'hsl(142.1 70.6% 45.3%)')};
      }

      .action-button.save:hover {
        background: ${cssManager.bdTheme('hsl(142.1 76.2% 36.3% / 0.1)', 'hsl(142.1 70.6% 45.3% / 0.1)')};
      }

      .action-button.cancel {
        color: ${cssManager.bdTheme('hsl(0 72.2% 50.6%)', 'hsl(0 62.8% 50.6%)')};
      }

      .action-button.cancel:hover {
        background: ${cssManager.bdTheme('hsl(0 72.2% 50.6% / 0.1)', 'hsl(0 62.8% 50.6% / 0.1)')};
      }

      .action-button.delete {
        color: ${cssManager.bdTheme('hsl(0 72.2% 50.6%)', 'hsl(0 62.8% 50.6%)')};
      }

      .action-button.delete:hover {
        background: ${cssManager.bdTheme('hsl(0 72.2% 50.6% / 0.1)', 'hsl(0 62.8% 50.6% / 0.1)')};
      }

      .action-button dees-icon {
        width: 14px;
        height: 14px;
      }

      .add-item-container {
        display: flex;
        gap: 8px;
        padding: 12px 16px;
        background: ${cssManager.bdTheme('hsl(0 0% 97.5%)', 'hsl(0 0% 6.9%)')};
        border-top: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')};
      }

      .add-input {
        flex: 1;
        padding: 8px 12px;
        font-size: 14px;
        font-family: inherit;
        background: ${cssManager.bdTheme('hsl(0 0% 100%)', 'hsl(0 0% 9%)')};
        border: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')};
        border-radius: 4px;
        outline: none;
        color: ${cssManager.bdTheme('hsl(0 0% 9%)', 'hsl(0 0% 95%)')};
        transition: all 0.15s ease;
      }

      .add-input:focus {
        border-color: ${cssManager.bdTheme('hsl(222.2 47.4% 51.2%)', 'hsl(217.2 91.2% 59.8%)')};
        box-shadow: 0 0 0 3px ${cssManager.bdTheme('hsl(222.2 47.4% 51.2% / 0.1)', 'hsl(217.2 91.2% 59.8% / 0.1)')};
      }

      .add-input::placeholder {
        color: ${cssManager.bdTheme('hsl(0 0% 63.9%)', 'hsl(0 0% 45.1%)')};
      }

      .add-input:disabled {
        cursor: not-allowed;
        opacity: 0.5;
      }

      .add-button {
        padding: 8px 16px;
      }

      .empty-state {
        padding: 32px 16px;
        text-align: center;
        color: ${cssManager.bdTheme('hsl(0 0% 63.9%)', 'hsl(0 0% 45.1%)')};
        font-size: 14px;
        font-style: italic;
      }

      .validation-message {
        color: ${cssManager.bdTheme('hsl(0 72.2% 50.6%)', 'hsl(0 62.8% 30.6%)')};
        font-size: 13px;
        margin-top: 6px;
        line-height: 1.5;
      }

      .description {
        color: ${cssManager.bdTheme('hsl(215.4 16.3% 56.9%)', 'hsl(215 20.2% 55.1%)')};
        font-size: 13px;
        margin-top: 6px;
        line-height: 1.5;
      }

      /* Scrollbar styling */
      .list-items::-webkit-scrollbar {
        width: 8px;
      }

      .list-items::-webkit-scrollbar-track {
        background: transparent;
      }

      .list-items::-webkit-scrollbar-thumb {
        background: ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 24.9%)')};
        border-radius: 4px;
      }

      .list-items::-webkit-scrollbar-thumb:hover {
        background: ${cssManager.bdTheme('hsl(0 0% 79.8%)', 'hsl(0 0% 34.9%)')};
      }

      /* Animation for adding/removing items */
      @keyframes slideIn {
        from {
          opacity: 0;
          transform: translateY(-10px);
        }
        to {
          opacity: 1;
          transform: translateY(0);
        }
      }

      .list-item {
        animation: slideIn 0.2s ease;
      }

      /* Override any inherited contain/content-visibility that might cause scrolling issues */
      .list-items, .list-item {
        content-visibility: visible !important;
        contain: none !important;
        contain-intrinsic-size: auto !important;
      }
    `,
  ];

  public render(): TemplateResult {
    return html`
      <div class="input-wrapper">
        ${this.label ? html`<dees-label .label=${this.label} .required=${this.required}></dees-label>` : ''}
        
        <div class="list-container ${this.disabled ? 'disabled' : ''}">
          <div class="list-items">
            ${this.value.length > 0 ? this.value.map((item, index) => html`
              <div
                class="list-item ${this.draggedIndex === index ? 'dragging' : ''} ${this.dragOverIndex === index ? 'drag-over' : ''}"
                draggable="${this.sortable && !this.disabled}"
                @dragstart=${(e: DragEvent) => this.handleDragStart(e, index)}
                @dragend=${this.handleDragEnd}
                @dragover=${(e: DragEvent) => this.handleDragOver(e, index)}
                @dragleave=${this.handleDragLeave}
                @drop=${(e: DragEvent) => this.handleDrop(e, index)}
              >
                ${this.sortable && !this.disabled ? html`
                  <div class="drag-handle">
                    <dees-icon .icon=${'lucide:gripVertical'}></dees-icon>
                  </div>
                ` : ''}
                
                <div class="item-content">
                  ${this.editingIndex === index ? html`
                    <input
                      type="text"
                      class="item-edit-input"
                      .value=${this.editingValue}
                      @input=${(e: InputEvent) => this.editingValue = (e.target as HTMLInputElement).value}
                      @keydown=${(e: KeyboardEvent) => this.handleEditKeyDown(e, index)}
                      @blur=${() => this.saveEdit(index)}
                    />
                  ` : html`
                    <div class="item-text" @dblclick=${() => !this.disabled && this.startEdit(index)}>
                      ${item}
                    </div>
                  `}
                </div>
                
                <div class="item-actions">
                  ${this.editingIndex === index ? html`
                    <button class="action-button save" @click=${() => this.saveEdit(index)}>
                      <dees-icon .icon=${'lucide:check'}></dees-icon>
                    </button>
                    <button class="action-button cancel" @click=${() => this.cancelEdit()}>
                      <dees-icon .icon=${'lucide:x'}></dees-icon>
                    </button>
                  ` : html`
                    ${!this.disabled ? html`
                      <button class="action-button" @click=${() => this.startEdit(index)}>
                        <dees-icon .icon=${'lucide:pencil'}></dees-icon>
                      </button>
                      <button class="action-button delete" @click=${() => this.removeItem(index)}>
                        <dees-icon .icon=${'lucide:trash2'}></dees-icon>
                      </button>
                    ` : ''}
                  `}
                </div>
              </div>
            `) : html`
              <div class="empty-state">
                No items added yet
              </div>
            `}
          </div>
          
          ${!this.disabled && (!this.maxItems || this.value.length < this.maxItems) ? html`
            <div class="add-item-container">
              <input
                type="text"
                class="add-input"
                .placeholder=${this.placeholder}
                .value=${this.inputValue}
                @input=${this.handleInput}
                @keydown=${this.handleAddKeyDown}
                ?disabled=${this.disabled}
              />
              <dees-button
                class="add-button"
                @click=${this.addItem}
                ?disabled=${!this.inputValue.trim()}
              >
                <dees-icon .icon=${'lucide:plus'}></dees-icon> Add
              </dees-button>
            </div>
          ` : ''}
        </div>

        ${this.validationText ? html`
          <div class="validation-message">${this.validationText}</div>
        ` : ''}
        
        ${this.description ? html`
          <div class="description">${this.description}</div>
        ` : ''}
      </div>
    `;
  }

  private handleInput(e: InputEvent) {
    this.inputValue = (e.target as HTMLInputElement).value;
  }

  private handleAddKeyDown(e: KeyboardEvent) {
    if (e.key === 'Enter' && this.inputValue.trim()) {
      e.preventDefault();
      this.addItem();
    }
  }

  private handleEditKeyDown(e: KeyboardEvent, index: number) {
    if (e.key === 'Enter') {
      e.preventDefault();
      this.saveEdit(index);
    } else if (e.key === 'Escape') {
      e.preventDefault();
      this.cancelEdit();
    }
  }

  private addItem() {
    const trimmedValue = this.inputValue.trim();
    if (!trimmedValue) return;

    if (!this.allowDuplicates && this.value.includes(trimmedValue)) {
      this.validationText = 'This item already exists in the list';
      setTimeout(() => this.validationText = '', 3000);
      return;
    }

    if (this.maxItems && this.value.length >= this.maxItems) {
      this.validationText = `Maximum ${this.maxItems} items allowed`;
      setTimeout(() => this.validationText = '', 3000);
      return;
    }

    this.value = [...this.value, trimmedValue];
    this.inputValue = '';
    this.validationText = '';
    
    // Clear the input
    const input = this.shadowRoot?.querySelector('.add-input') as HTMLInputElement;
    if (input) {
      input.value = '';
      input.focus();
    }

    this.emitChange();
  }

  private startEdit(index: number) {
    this.editingIndex = index;
    this.editingValue = this.value[index];
    
    // Focus the input after render
    this.updateComplete.then(() => {
      const input = this.shadowRoot?.querySelector('.item-edit-input') as HTMLInputElement;
      if (input) {
        input.focus();
        input.select();
      }
    });
  }

  private saveEdit(index: number) {
    const trimmedValue = this.editingValue.trim();
    
    if (!trimmedValue) {
      this.cancelEdit();
      return;
    }

    if (!this.allowDuplicates && trimmedValue !== this.value[index] && this.value.includes(trimmedValue)) {
      this.validationText = 'This item already exists in the list';
      setTimeout(() => this.validationText = '', 3000);
      return;
    }

    const newValue = [...this.value];
    newValue[index] = trimmedValue;
    this.value = newValue;
    
    this.editingIndex = -1;
    this.editingValue = '';
    this.validationText = '';
    this.emitChange();
  }

  private cancelEdit() {
    this.editingIndex = -1;
    this.editingValue = '';
  }

  private async removeItem(index: number) {
    if (this.confirmDelete) {
      const confirmed = await this.showConfirmDialog(`Delete "${this.value[index]}"?`);
      if (!confirmed) return;
    }

    this.value = this.value.filter((_, i) => i !== index);
    this.emitChange();
  }

  private async showConfirmDialog(message: string): Promise<boolean> {
    // For now, use native confirm. In production, this should use a proper modal
    return confirm(message);
  }

  // Drag and drop handlers
  private handleDragStart(e: DragEvent, index: number) {
    if (!this.sortable || this.disabled) return;
    
    this.draggedIndex = index;
    e.dataTransfer!.effectAllowed = 'move';
    e.dataTransfer!.setData('text/plain', index.toString());
  }

  private handleDragEnd() {
    this.draggedIndex = -1;
    this.dragOverIndex = -1;
  }

  private handleDragOver(e: DragEvent, index: number) {
    if (!this.sortable || this.disabled) return;
    
    e.preventDefault();
    e.dataTransfer!.dropEffect = 'move';
    this.dragOverIndex = index;
  }

  private handleDragLeave() {
    this.dragOverIndex = -1;
  }

  private handleDrop(e: DragEvent, dropIndex: number) {
    if (!this.sortable || this.disabled) return;
    
    e.preventDefault();
    const draggedIndex = parseInt(e.dataTransfer!.getData('text/plain'));
    
    if (draggedIndex !== dropIndex) {
      const newValue = [...this.value];
      const [draggedItem] = newValue.splice(draggedIndex, 1);
      newValue.splice(dropIndex, 0, draggedItem);
      this.value = newValue;
      this.emitChange();
    }
    
    this.draggedIndex = -1;
    this.dragOverIndex = -1;
  }

  private emitChange() {
    this.dispatchEvent(new CustomEvent('change', {
      detail: { value: this.value },
      bubbles: true,
      composed: true
    }));
    this.changeSubject.next(this);
  }

  public getValue(): string[] {
    return this.value;
  }

  public setValue(value: string[]): void {
    this.value = value || [];
  }

  public async validate(): Promise<boolean> {
    if (this.required && (!this.value || this.value.length === 0)) {
      this.validationText = 'At least one item is required';
      return false;
    }
    
    if (this.minItems && this.value.length < this.minItems) {
      this.validationText = `At least ${this.minItems} items required`;
      return false;
    }
    
    this.validationText = '';
    return true;
  }
}