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

import { WysiwygFormatting } from './wysiwyg.formatting.js';
import { themeDefaultStyles } from '../../00theme.js';

declare global {
  interface HTMLElementTagNameMap {
    'dees-formatting-menu': DeesFormattingMenu;
  }
}

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

  @state()
  accessor visible: boolean = false;

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

  @state()
  accessor menuZIndex: number = 1000;

  private callback: ((command: string) => void | Promise<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;
      }

      .formatting-menu {
        position: fixed;
        background: ${cssManager.bdTheme('#ffffff', '#262626')};
        border: 1px solid ${cssManager.bdTheme('#e0e0e0', '#404040')};
        border-radius: 6px;
        box-shadow: 0 2px 16px rgba(0, 0, 0, 0.15);
        padding: 4px;
        display: flex;
        gap: 2px;
        pointer-events: auto;
        user-select: none;
        animation: fadeInScale 0.15s ease-out;
      }

      @keyframes fadeInScale {
        from {
          opacity: 0;
          transform: scale(0.95) translateY(5px);
        }
        to {
          opacity: 1;
          transform: scale(1) translateY(0);
        }
      }

      .format-button {
        width: 32px;
        height: 32px;
        border: none;
        background: transparent;
        cursor: pointer;
        border-radius: 4px;
        transition: all 0.15s ease;
        display: flex;
        align-items: center;
        justify-content: center;
        color: ${cssManager.bdTheme('#000000', '#e0e0e0')};
        font-weight: 600;
        font-size: 14px;
        position: relative;
      }

      .format-button:hover {
        background: ${cssManager.bdTheme('#f0f0f0', '#333333')};
        color: ${cssManager.bdTheme('#0066cc', '#4d94ff')};
      }

      .format-button:active {
        transform: scale(0.95);
      }

      .format-button.bold {
        font-weight: 700;
      }

      .format-button.italic {
        font-style: italic;
      }

      .format-button.underline {
        text-decoration: underline;
      }

      .format-button .code-icon {
        font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Code', monospace;
        font-size: 12px;
      }
    `,
  ];

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

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

    return html`
      <div 
        class="formatting-menu" 
        style="left: ${this.position.x}px; top: ${this.position.y}px;"
        tabindex="-1"
        data-menu-type="formatting"
      >
        ${WysiwygFormatting.formatButtons.map(button => html`
          <button 
            class="format-button ${button.command}"
            data-command="${button.command}"
            title="${button.label}${button.shortcut ? ` (${button.shortcut})` : ''}"
          >
            <span class="${button.command === 'code' ? 'code-icon' : ''}">${button.icon}</span>
          </button>
        `)}
      </div>
    `;
  }

  private applyFormat(command: string): void {
    if (this.callback) {
      this.callback(command);
    }
    // Don't hide menu after applying format (except for link)
    if (command === 'link') {
      this.hide();
    }
  }

  public show(position: { x: number; y: number }, callback: (command: string) => void | Promise<void>): void {
    console.log('FormattingMenu.show called:', { position, visible: this.visible });
    this.position = position;
    this.callback = callback;
    
    // 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;
    
    // Unregister from z-index registry
    zIndexRegistry.unregister(this);
  }

  public updatePosition(position: { x: number; y: number }): void {
    this.position = position;
  }
  
  public firstUpdated(): void {
    // Set up event delegation for the menu
    this.shadowRoot?.addEventListener('mousedown', (e: MouseEvent) => {
      const menu = this.shadowRoot?.querySelector('.formatting-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 button = target.closest('.format-button') as HTMLElement;
      
      if (button) {
        e.preventDefault();
        e.stopPropagation();
        
        const command = button.getAttribute('data-command');
        if (command) {
          this.applyFormat(command);
        }
      }
    });
    
    this.shadowRoot?.addEventListener('focus', (e: FocusEvent) => {
      const menu = this.shadowRoot?.querySelector('.formatting-menu');
      if (menu && menu.contains(e.target as Node)) {
        // Prevent menu from taking focus
        e.preventDefault();
        e.stopPropagation();
      }
    }, true); // Use capture phase
  }
}