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

import * as domtools from '@design.estate/dees-domtools';
import * as interfaces from '../../interfaces/index.js';
import * as plugins from '../../00plugins.js';
import { demoFunc } from './demo.js';
import { appuiAppbarStyles } from './styles.js';
import { renderAppuiAppbar } from './template.js';

// Import required components
import '../../dees-icon/dees-icon.js';
import '../../dees-windowcontrols/dees-windowcontrols.js';
import '../dees-appui-profiledropdown/dees-appui-profiledropdown.js';

declare global {
  interface HTMLElementTagNameMap {
    'dees-appui-appbar': DeesAppuiBar;
  }
}

@customElement('dees-appui-appbar')
export class DeesAppuiBar extends DeesElement {
  public static demo = demoFunc;
  public static demoGroup = 'App UI';

  // INSTANCE PROPERTIES
  @property({ type: Array })
  accessor menuItems: interfaces.IAppBarMenuItem[] = [];

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

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

  @property({ type: Boolean })
  accessor showWindowControls: boolean = true;


  @property({ type: Object })
  accessor user: {
    name: string;
    email?: string;
    avatar?: string;
    status?: 'online' | 'offline' | 'busy' | 'away';
  } | undefined = undefined;

  @property({ type: Array })
  accessor profileMenuItems: (plugins.tsclass.website.IMenuItem & { shortcut?: string } | { divider: true })[] = [];

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

  // Activity log toggle
  @property({ type: Boolean })
  accessor showActivityLogToggle: boolean = false;

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

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

  // STATE
  @state()
  accessor activeMenu: string | null = null;

  @state()
  accessor openDropdowns: Set<string> = new Set();

  @state()
  accessor focusedItem: string | null = null;

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

  @state()
  accessor isProfileDropdownOpen: boolean = false;

  public static styles = appuiAppbarStyles;

  // INSTANCE
  public render(): TemplateResult {
    return renderAppuiAppbar(this);
  }



  public renderMenuItems(): TemplateResult {
    return html`
      ${this.menuItems.map((item, index) => this.renderMenuItem(item, `menu-${index}`))}
    `;
  }

  private renderMenuItem(item: interfaces.IAppBarMenuItem, itemId: string): TemplateResult {
    if ('divider' in item && item.divider) {
      return html`<div class="dropdown-divider"></div>`;
    }

    const menuItem = item as interfaces.IAppBarMenuItemRegular;
    const isActive = this.activeMenu === itemId;
    const hasSubmenu = menuItem.submenu && menuItem.submenu.length > 0;

    return html`
      <div
        class="menuItem ${isActive ? 'active' : ''}"
        ?disabled=${menuItem.disabled}
        tabindex="${menuItem.disabled ? -1 : 0}"
        data-item-id="${itemId}"
        @click=${() => this.handleMenuClick(menuItem, itemId)}
        @keydown=${(e: KeyboardEvent) => this.handleMenuKeydown(e, menuItem, itemId)}
        role="menuitem"
        aria-haspopup="${hasSubmenu}"
        aria-expanded="${isActive}"
      >
        ${menuItem.iconName ? html`<dees-icon .icon="${`lucide:${menuItem.iconName}`}"></dees-icon>` : ''}
        ${menuItem.name}
        ${hasSubmenu ? this.renderDropdown(menuItem.submenu, itemId, isActive) : ''}
      </div>
    `;
  }

  private renderDropdown(items: interfaces.IAppBarMenuItem[], parentId: string, isOpen: boolean): TemplateResult {
    return html`
      <div 
        class="dropdown ${isOpen ? 'open' : ''}" 
        @click=${(e: Event) => e.stopPropagation()}
        @keydown=${(e: KeyboardEvent) => this.handleDropdownKeydown(e, items, parentId)}
        tabindex="${isOpen ? 0 : -1}"
        role="menu"
      >
        ${items.map((item, index) => this.renderDropdownItem(item, `${parentId}-${index}`))}
      </div>
    `;
  }

  private renderDropdownItem(item: interfaces.IAppBarMenuItem, itemId: string): TemplateResult {
    if ('divider' in item && item.divider) {
      return html`<div class="dropdown-divider"></div>`;
    }

    const menuItem = item as interfaces.IAppBarMenuItemRegular;
    const itemIndex = parseInt(itemId.split('-').pop() || '0');
    const isFocused = this.focusedDropdownItem === itemIndex;
    
    return html`
      <div
        class="dropdown-item ${isFocused ? 'focused' : ''}"
        ?disabled=${menuItem.disabled}
        @click=${() => this.handleDropdownItemClick(menuItem)}
        @mouseenter=${() => this.focusedDropdownItem = itemIndex}
        role="menuitem"
        tabindex="${menuItem.disabled ? -1 : 0}"
      >
        ${menuItem.iconName ? html`<dees-icon .icon="${`lucide:${menuItem.iconName}`}"></dees-icon>` : ''}
        <span>${menuItem.name}</span>
        ${menuItem.shortcut ? html`<span class="shortcut">${menuItem.shortcut}</span>` : ''}
      </div>
    `;
  }

  public renderBreadcrumbs(): TemplateResult {
    if (!this.breadcrumbs) {
      return html``;
    }

    const parts = this.breadcrumbs.split(this.breadcrumbSeparator);
    return html`
      ${parts.map((part, index) => html`
        ${index > 0 ? html`<span class="breadcrumb-separator">${this.breadcrumbSeparator}</span>` : ''}
        <span 
          class="breadcrumb-item" 
          @click=${() => this.handleBreadcrumbClick(part, index)}
        >
          ${part}
        </span>
      `)}
    `;
  }

  public renderAccountSection(): TemplateResult {
    return html`
      ${this.showSearch ? html`
        <dees-icon
          class="search-icon"
          .icon=${'lucide:search'}
          @click=${this.handleSearchClick}
        ></dees-icon>
      ` : ''}
      ${this.user ? html`
        <div style="position: relative;">
          <div class="user-info" @click=${this.handleUserClick}>
            <div class="user-avatar">
              ${this.user.avatar ? 
                html`<img src="${this.user.avatar}" alt="${this.user.name}">` : 
                html`${this.user.name.charAt(0).toUpperCase()}`
              }
              ${this.user.status ? html`
                <div class="user-status ${this.user.status}"></div>
              ` : ''}
            </div>
            <span>${this.user.name}</span>
          </div>
          <dees-appui-profiledropdown
            .user=${this.user}
            .menuItems=${this.profileMenuItems}
            .isOpen=${this.isProfileDropdownOpen}
            .position=${'top-right'}
            @menu-select=${(e: CustomEvent) => this.handleProfileMenuSelect(e)}
          ></dees-appui-profiledropdown>
        </div>
      ` : ''}
      ${this.showActivityLogToggle ? html`
        <div
          class="activity-toggle ${this.activityLogActive ? 'active' : ''}"
          @click=${this.handleActivityToggle}
          title="Activity Log"
        >
          <dees-icon .icon=${'lucide:activity'}></dees-icon>
          ${this.activityLogCount > 0 ? html`
            <span class="activity-badge">${this.activityLogCount > 99 ? '99+' : this.activityLogCount}</span>
          ` : ''}
        </div>
      ` : ''}
    `;
  }

  // Event handlers
  private handleMenuClick(item: interfaces.IAppBarMenuItemRegular, itemId: string) {
    if (item.disabled) return;

    if (item.submenu && item.submenu.length > 0) {
      // Toggle dropdown
      if (this.activeMenu === itemId) {
        this.activeMenu = null;
      } else {
        this.activeMenu = itemId;
      }
    } else {
      // Execute action
      this.activeMenu = null;
      if (item.action) {
        item.action();
      }
      this.dispatchEvent(new CustomEvent('menu-select', { 
        detail: { item },
        bubbles: true,
        composed: true 
      }));
    }
  }

  private handleDropdownItemClick(item: interfaces.IAppBarMenuItemRegular) {
    if (item.disabled) return;

    this.activeMenu = null;
    if (item.action) {
      item.action();
    }
    this.dispatchEvent(new CustomEvent('menu-select', { 
      detail: { item },
      bubbles: true,
      composed: true 
    }));
  }

  private handleMenuKeydown(e: KeyboardEvent, item: interfaces.IAppBarMenuItemRegular, itemId: string) {
    switch (e.key) {
      case 'Enter':
      case ' ':
        e.preventDefault();
        this.handleMenuClick(item, itemId);
        break;
      case 'ArrowDown':
        if (item.submenu && this.activeMenu === itemId) {
          e.preventDefault();
          // Focus first non-disabled item in dropdown
          this.focusedDropdownItem = 0;
          const firstValidItem = this.findNextValidItem(item.submenu, -1, 1);
          if (firstValidItem !== -1) {
            this.focusedDropdownItem = firstValidItem;
            // Focus the dropdown element
            setTimeout(() => {
              const dropdown = this.renderRoot.querySelector('.dropdown.open');
              if (dropdown) {
                (dropdown as HTMLElement).focus();
              }
            }, 0);
          }
        }
        break;
      case 'Escape':
        this.activeMenu = null;
        this.focusedDropdownItem = -1;
        break;
      case 'Tab':
        // Let default tab navigation work but close dropdown
        if (this.activeMenu === itemId) {
          this.activeMenu = null;
          this.focusedDropdownItem = -1;
        }
        break;
      case 'ArrowRight':
        e.preventDefault();
        this.focusNextMenuItem(itemId, 1);
        break;
      case 'ArrowLeft':
        e.preventDefault();
        this.focusNextMenuItem(itemId, -1);
        break;
    }
  }

  private handleBreadcrumbClick(breadcrumb: string, index: number) {
    this.dispatchEvent(new CustomEvent('breadcrumb-navigate', { 
      detail: { breadcrumb, index },
      bubbles: true,
      composed: true 
    }));
  }

  private handleSearchClick() {
    this.dispatchEvent(new CustomEvent('search-click', {
      bubbles: true,
      composed: true
    }));
  }

  private handleActivityToggle() {
    this.dispatchEvent(new CustomEvent('activity-toggle', {
      bubbles: true,
      composed: true
    }));
  }

  private handleUserClick() {
    this.isProfileDropdownOpen = !this.isProfileDropdownOpen;
    
    // Also emit the event for backward compatibility
    this.dispatchEvent(new CustomEvent('user-menu-open', { 
      bubbles: true,
      composed: true 
    }));
  }

  private handleProfileMenuSelect(e: CustomEvent) {
    this.isProfileDropdownOpen = false;
    
    // Re-emit the event
    this.dispatchEvent(new CustomEvent('profile-menu-select', { 
      detail: e.detail,
      bubbles: true,
      composed: true 
    }));
  }

  // Lifecycle
  async connectedCallback() {
    await super.connectedCallback();
    // Add global click listener to close dropdowns
    this.addEventListener('click', this.handleGlobalClick);
    document.addEventListener('click', this.handleDocumentClick);
  }

  async disconnectedCallback() {
    await super.disconnectedCallback();
    document.removeEventListener('click', this.handleDocumentClick);
  }

  private handleGlobalClick = (e: Event) => {
    // Prevent closing when clicking inside
    e.stopPropagation();
  }

  private handleDocumentClick = () => {
    // Close all dropdowns when clicking outside
    this.activeMenu = null;
    this.focusedDropdownItem = -1;
    // Note: Profile dropdown handles its own outside clicks
  }

  private handleDropdownKeydown(e: KeyboardEvent, items: interfaces.IAppBarMenuItem[], _parentId: string) {
    const validItems = items.filter(item => !('divider' in item && item.divider));
    
    switch (e.key) {
      case 'ArrowDown':
        e.preventDefault();
        const nextIndex = this.findNextValidItem(items, this.focusedDropdownItem, 1);
        if (nextIndex !== -1) {
          this.focusedDropdownItem = nextIndex;
        }
        break;
      case 'ArrowUp':
        e.preventDefault();
        const prevIndex = this.findNextValidItem(items, this.focusedDropdownItem, -1);
        if (prevIndex !== -1) {
          this.focusedDropdownItem = prevIndex;
        }
        break;
      case 'Enter':
        e.preventDefault();
        if (this.focusedDropdownItem !== -1) {
          const focusedItem = validItems[this.focusedDropdownItem];
          if (focusedItem && 'action' in focusedItem && !focusedItem.disabled) {
            this.handleDropdownItemClick(focusedItem as interfaces.IAppBarMenuItemRegular);
          }
        }
        break;
      case 'Home':
        e.preventDefault();
        const firstIndex = this.findNextValidItem(items, -1, 1);
        if (firstIndex !== -1) {
          this.focusedDropdownItem = firstIndex;
        }
        break;
      case 'End':
        e.preventDefault();
        const lastIndex = this.findNextValidItem(items, items.length, -1);
        if (lastIndex !== -1) {
          this.focusedDropdownItem = lastIndex;
        }
        break;
      case 'Escape':
        e.preventDefault();
        this.activeMenu = null;
        this.focusedDropdownItem = -1;
        // Return focus to menu item
        const menuItem = this.renderRoot.querySelector(`.menuItem.active`);
        if (menuItem) {
          (menuItem as HTMLElement).focus();
        }
        break;
    }
  }

  private findNextValidItem(items: interfaces.IAppBarMenuItem[], currentIndex: number, direction: number): number {
    let index = currentIndex + direction;
    
    while (index >= 0 && index < items.length) {
      const item = items[index];
      // Skip dividers and disabled items
      if (!('divider' in item && item.divider) && !('disabled' in item && item.disabled)) {
        return index;
      }
      index += direction;
    }
    
    return -1;
  }

  private focusNextMenuItem(currentItemId: string, direction: number) {
    const menuItems = Array.from(this.renderRoot.querySelectorAll('.menuItem'));
    const currentIndex = menuItems.findIndex(item => item.getAttribute('data-item-id') === currentItemId);
    
    if (currentIndex === -1) return;
    
    let nextIndex = currentIndex + direction;
    
    // Wrap around
    if (nextIndex < 0) {
      nextIndex = menuItems.length - 1;
    } else if (nextIndex >= menuItems.length) {
      nextIndex = 0;
    }
    
    // Find next non-disabled item
    let attempts = 0;
    while (attempts < menuItems.length) {
      const nextItem = menuItems[nextIndex] as HTMLElement;
      if (!nextItem.hasAttribute('disabled')) {
        nextItem.focus();
        // Close current dropdown if open
        if (this.activeMenu) {
          this.activeMenu = null;
          this.focusedDropdownItem = -1;
        }
        break;
      }
      nextIndex = (nextIndex + direction + menuItems.length) % menuItems.length;
      attempts++;
    }
  }
}
