import {
  customElement,
  html,
  DeesElement,
  type TemplateResult,
  cssManager,
  css,
  state,
} from '@design.estate/dees-element';
import { zIndexRegistry } from '../../00zindex.js';
import '../../dees-icon/dees-icon.js';

import { type ISlashMenuItem } from './wysiwyg.types.js';
import { WysiwygShortcuts } from './wysiwyg.shortcuts.js';
import { themeDefaultStyles } from '../../00theme.js';

declare global {
  interface HTMLElementTagNameMap {
    'dees-slash-menu': DeesSlashMenu;
  }
}

@customElement('dees-slash-menu')
export class DeesSlashMenu extends DeesElement {
  private static instance: DeesSlashMenu;
  
  public static getInstance(): DeesSlashMenu {
    if (!DeesSlashMenu.instance) {
      DeesSlashMenu.instance = new DeesSlashMenu();
      document.body.appendChild(DeesSlashMenu.instance);
    }
    return DeesSlashMenu.instance;
  }

  @state()
  accessor visible: boolean = false;

  @state()
  accessor position: { x: number; y: number } = { x: 0, y: 0 };

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

  @state()
  accessor selectedIndex: number = 0;

  @state()
  accessor menuZIndex: number = 1000;

  private callback: ((type: string) => void) | null = null;

  public static styles = [
    themeDefaultStyles,
    cssManager.defaultStyles,
    css`
      /* TODO: Migrate hardcoded values to --dees-* CSS variables */
      :host {
        position: fixed;
        pointer-events: none;
        top: 0;
        left: 0;
        width: 0;
        height: 0;
      }

      .slash-menu {
        position: fixed;
        background: ${cssManager.bdTheme('#ffffff', '#09090b')};
        border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
        border-radius: 4px;
        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06);
        padding: 4px;
        min-width: 220px;
        max-height: 300px;
        overflow-y: auto;
        pointer-events: auto;
        user-select: none;
        animation: fadeInScale 0.15s ease-out;
      }

      @keyframes fadeInScale {
        from {
          opacity: 0;
          transform: scale(0.98) translateY(-2px);
        }
        to {
          opacity: 1;
          transform: scale(1) translateY(0);
        }
      }

      .slash-menu-item {
        padding: 8px 10px;
        cursor: pointer;
        transition: all 0.15s ease;
        display: flex;
        align-items: center;
        gap: 12px;
        border-radius: 3px;
        color: ${cssManager.bdTheme('#09090b', '#fafafa')};
        font-size: 14px;
      }

      .slash-menu-item:hover,
      .slash-menu-item.selected {
        background: ${cssManager.bdTheme('#f4f4f5', '#27272a')};
        color: ${cssManager.bdTheme('#09090b', '#fafafa')};
      }

      .slash-menu-item .icon {
        width: 20px;
        height: 20px;
        display: flex;
        align-items: center;
        justify-content: center;
        color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
      }

      .slash-menu-item:hover .icon,
      .slash-menu-item.selected .icon {
        color: ${cssManager.bdTheme('#3b82f6', '#3b82f6')};
      }
    `,
  ];

  render(): TemplateResult {
    if (!this.visible) return html``;

    // Ensure z-index is applied to host element
    this.style.zIndex = this.menuZIndex.toString();

    const menuItems = this.getFilteredMenuItems();

    return html`
      <div 
        class="slash-menu" 
        style="left: ${this.position.x}px; top: ${this.position.y}px;"
        tabindex="-1"
        data-menu-type="slash"
      >
        ${menuItems.map((item, index) => html`
          <div 
            class="slash-menu-item ${index === this.selectedIndex ? 'selected' : ''}"
            data-item-type="${item.type}"
            data-item-index="${index}"
          >
            <dees-icon class="icon" .icon="${item.icon}" iconSize="16"></dees-icon>
            <span>${item.label}</span>
          </div>
        `)}
      </div>
    `;
  }

  private getFilteredMenuItems(): ISlashMenuItem[] {
    const allItems = WysiwygShortcuts.getSlashMenuItems();
    return allItems.filter(item => 
      this.filter === '' || 
      item.label.toLowerCase().includes(this.filter.toLowerCase())
    );
  }

  private selectItem(type: string): void {
    if (this.callback) {
      this.callback(type);
    }
    this.hide();
  }

  public show(position: { x: number; y: number }, callback: (type: string) => void): void {
    this.position = position;
    this.callback = callback;
    this.filter = '';
    this.selectedIndex = 0;
    
    // Get z-index from registry and apply immediately
    this.menuZIndex = zIndexRegistry.getNextZIndex();
    zIndexRegistry.register(this, this.menuZIndex);
    this.style.zIndex = this.menuZIndex.toString();
    
    this.visible = true;
  }

  public hide(): void {
    this.visible = false;
    this.callback = null;
    this.filter = '';
    this.selectedIndex = 0;
    
    // Unregister from z-index registry
    zIndexRegistry.unregister(this);
  }

  public updateFilter(filter: string): void {
    this.filter = filter;
    this.selectedIndex = 0;
  }

  public navigate(direction: 'up' | 'down'): void {
    const items = this.getFilteredMenuItems();
    if (direction === 'down') {
      this.selectedIndex = (this.selectedIndex + 1) % items.length;
    } else {
      this.selectedIndex = this.selectedIndex === 0 
        ? items.length - 1 
        : this.selectedIndex - 1;
    }
  }

  public selectCurrent(): void {
    const items = this.getFilteredMenuItems();
    if (items[this.selectedIndex]) {
      this.selectItem(items[this.selectedIndex].type);
    }
  }
  
  public firstUpdated(): void {
    // Set up event delegation
    this.shadowRoot?.addEventListener('mousedown', (e: MouseEvent) => {
      const menu = this.shadowRoot?.querySelector('.slash-menu');
      if (menu && menu.contains(e.target as Node)) {
        // Prevent focus loss
        e.preventDefault();
        e.stopPropagation();
      }
    });
    
    this.shadowRoot?.addEventListener('click', (e: MouseEvent) => {
      const target = e.target as HTMLElement;
      const menuItem = target.closest('.slash-menu-item') as HTMLElement;
      
      if (menuItem) {
        e.preventDefault();
        e.stopPropagation();
        
        const itemType = menuItem.getAttribute('data-item-type');
        if (itemType) {
          this.selectItem(itemType);
        }
      }
    });
    
    this.shadowRoot?.addEventListener('mouseenter', (e: MouseEvent) => {
      const target = e.target as HTMLElement;
      const menuItem = target.closest('.slash-menu-item') as HTMLElement;
      
      if (menuItem) {
        const index = parseInt(menuItem.getAttribute('data-item-index') || '0', 10);
        this.selectedIndex = index;
      }
    }, true); // Use capture phase
    
    this.shadowRoot?.addEventListener('focus', (e: FocusEvent) => {
      const menu = this.shadowRoot?.querySelector('.slash-menu');
      if (menu && menu.contains(e.target as Node)) {
        // Prevent menu from taking focus
        e.preventDefault();
        e.stopPropagation();
      }
    }, true); // Use capture phase
  }
}