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

export interface IContextMenuItem {
  name: string;
  iconName?: string;
  action: () => void | Promise<void>;
  disabled?: boolean;
}

@customElement('wcc-contextmenu')
export class WccContextmenu extends DeesElement {
  // Static method to show context menu at position
  public static async show(
    event: MouseEvent,
    menuItems: IContextMenuItem[]
  ): Promise<void> {
    event.preventDefault();
    event.stopPropagation();

    // Remove any existing context menu
    const existing = document.querySelector('wcc-contextmenu');
    if (existing) {
      existing.remove();
    }

    const menu = new WccContextmenu();
    menu.menuItems = menuItems;
    menu.x = event.clientX;
    menu.y = event.clientY;

    document.body.appendChild(menu);

    // Wait for render then adjust position if needed
    await menu.updateComplete;
    menu.adjustPosition();
  }

  @property({ type: Array })
  accessor menuItems: IContextMenuItem[] = [];

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

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

  @state()
  accessor visible: boolean = false;

  private boundHandleOutsideClick = this.handleOutsideClick.bind(this);
  private boundHandleKeydown = this.handleKeydown.bind(this);

  public static styles = [
    css`
      :host {
        position: fixed;
        z-index: 10000;
        opacity: 0;
        transform: scale(0.95) translateY(-5px);
        transition: opacity 0.15s ease, transform 0.15s ease;
        pointer-events: none;
      }

      :host(.visible) {
        opacity: 1;
        transform: scale(1) translateY(0);
        pointer-events: auto;
      }

      .menu {
        min-width: 160px;
        background: #0f0f0f;
        border: 1px solid rgba(255, 255, 255, 0.1);
        border-radius: 6px;
        box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
        padding: 4px 0;
        font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
        font-size: 12px;
      }

      .menu-item {
        display: flex;
        align-items: center;
        gap: 8px;
        padding: 8px 12px;
        color: #ccc;
        cursor: pointer;
        transition: background 0.1s ease;
        user-select: none;
      }

      .menu-item:hover {
        background: rgba(59, 130, 246, 0.15);
        color: #fff;
      }

      .menu-item.disabled {
        opacity: 0.4;
        cursor: not-allowed;
        pointer-events: none;
      }

      .menu-item .icon {
        font-family: 'Material Symbols Outlined';
        font-size: 16px;
        font-weight: normal;
        font-style: normal;
        line-height: 1;
        letter-spacing: normal;
        text-transform: none;
        white-space: nowrap;
        word-wrap: normal;
        direction: ltr;
        font-variation-settings: 'FILL' 0, 'wght' 300, 'GRAD' 0, 'opsz' 24;
        opacity: 0.7;
      }

      .menu-item:hover .icon {
        opacity: 1;
      }

      .menu-item .label {
        flex: 1;
      }
    `
  ];

  public render(): TemplateResult {
    return html`
      <div class="menu">
        ${this.menuItems.map(item => html`
          <div
            class="menu-item ${item.disabled ? 'disabled' : ''}"
            @click=${() => this.handleItemClick(item)}
          >
            ${item.iconName ? html`<span class="icon">${item.iconName}</span>` : null}
            <span class="label">${item.name}</span>
          </div>
        `)}
      </div>
    `;
  }

  async connectedCallback() {
    await super.connectedCallback();
    // Delay adding listeners to avoid immediate close
    requestAnimationFrame(() => {
      document.addEventListener('click', this.boundHandleOutsideClick);
      document.addEventListener('contextmenu', this.boundHandleOutsideClick);
      document.addEventListener('keydown', this.boundHandleKeydown);
      this.classList.add('visible');
    });
  }

  async disconnectedCallback() {
    await super.disconnectedCallback();
    document.removeEventListener('click', this.boundHandleOutsideClick);
    document.removeEventListener('contextmenu', this.boundHandleOutsideClick);
    document.removeEventListener('keydown', this.boundHandleKeydown);
  }

  private adjustPosition() {
    const rect = this.getBoundingClientRect();
    const windowWidth = window.innerWidth;
    const windowHeight = window.innerHeight;

    let x = this.x;
    let y = this.y;

    // Adjust if menu goes off right edge
    if (x + rect.width > windowWidth - 10) {
      x = windowWidth - rect.width - 10;
    }

    // Adjust if menu goes off bottom edge
    if (y + rect.height > windowHeight - 10) {
      y = windowHeight - rect.height - 10;
    }

    // Ensure not off left or top
    if (x < 10) x = 10;
    if (y < 10) y = 10;

    this.style.left = `${x}px`;
    this.style.top = `${y}px`;
  }

  private handleOutsideClick(e: Event) {
    const path = e.composedPath();
    if (!path.includes(this)) {
      this.close();
    }
  }

  private handleKeydown(e: KeyboardEvent) {
    if (e.key === 'Escape') {
      this.close();
    }
  }

  private async handleItemClick(item: IContextMenuItem) {
    if (item.disabled) return;
    await item.action();
    this.close();
  }

  private close() {
    this.classList.remove('visible');
    setTimeout(() => this.remove(), 150);
  }
}
