/**
 * Drawer Controller
 *
 * Handles all drawer functionality including profile, notifications, and todo drawers
 */

export type DrawerName = 'profile' | 'notification' | 'todo' | 'newTodo';

export class DrawerController {
  private profileDrawer: HTMLElement | null = null;
  private notificationDrawer: HTMLElement | null = null;
  private todoDrawer: HTMLElement | null = null;
  private newTodoDrawer: HTMLElement | null = null;
  private overlay: HTMLElement | null = null;
  private activeDrawer: DrawerName | null = null;
  private activeGenericDrawer: HTMLElement | null = null;

  constructor() {
    this.profileDrawer = document.getElementById('profileDrawer');
    this.notificationDrawer = document.getElementById('notificationDrawer');
    this.todoDrawer = document.getElementById('todoDrawer');
    this.newTodoDrawer = document.getElementById('newTodoDrawer');
    this.overlay = document.getElementById('drawerOverlay');

    this.setupListeners();
    this.setupGenericDrawers();
  }

  /**
   * Get currently active drawer name
   */
  get active(): DrawerName | null {
    return this.activeDrawer;
  }

  /**
   * Open a drawer by name
   */
  open(name: DrawerName): void {
    this.closeAll();

    const drawer = this.getDrawer(name);
    if (drawer && this.overlay) {
      drawer.classList.add('active');
      this.overlay.classList.add('active');
      document.body.style.overflow = 'hidden';
      this.activeDrawer = name;
    }
  }

  /**
   * Close a specific drawer
   */
  close(name: DrawerName): void {
    const drawer = this.getDrawer(name);
    drawer?.classList.remove('active');

    // Only hide overlay if no drawers are active
    if (this.overlay && !document.querySelector('.active[class*="drawer"]')) {
      this.overlay.classList.remove('active');
      document.body.style.overflow = '';
    }

    if (this.activeDrawer === name) {
      this.activeDrawer = null;
    }
  }

  /**
   * Close all drawers
   */
  closeAll(): void {
    [this.profileDrawer, this.notificationDrawer, this.todoDrawer, this.newTodoDrawer]
      .forEach(drawer => drawer?.classList.remove('active'));

    // Close any generic drawers
    this.closeGenericDrawer();

    this.overlay?.classList.remove('active');
    document.body.style.overflow = '';
    this.activeDrawer = null;
  }

  /**
   * Open a generic drawer by ID
   */
  openGenericDrawer(drawerId: string): void {
    this.closeAll();

    const drawer = document.getElementById(drawerId);
    if (drawer && this.overlay) {
      drawer.classList.add('open');
      this.overlay.classList.add('active');
      document.body.style.overflow = 'hidden';
      this.activeGenericDrawer = drawer;
    }
  }

  /**
   * Close the currently open generic drawer
   */
  closeGenericDrawer(): void {
    this.activeGenericDrawer?.classList.remove('open');
    this.activeGenericDrawer = null;
  }

  /**
   * Open profile drawer
   */
  openProfile(): void {
    this.open('profile');
  }

  /**
   * Open notification drawer
   */
  openNotification(): void {
    this.open('notification');
  }

  /**
   * Open todo drawer (slides on top of profile)
   */
  openTodo(): void {
    this.todoDrawer?.classList.add('active');
  }

  /**
   * Close todo drawer
   */
  closeTodo(): void {
    this.todoDrawer?.classList.remove('active');
    this.closeNewTodo();
  }

  /**
   * Open new todo drawer
   */
  openNewTodo(): void {
    this.newTodoDrawer?.classList.add('active');
  }

  /**
   * Close new todo drawer
   */
  closeNewTodo(): void {
    this.newTodoDrawer?.classList.remove('active');
  }

  /**
   * Mark all notifications as read
   */
  markAllNotificationsRead(): void {
    if (!this.notificationDrawer) return;

    const unreadItems = this.notificationDrawer.querySelectorAll<HTMLElement>(
      'swp-notification-item[data-unread="true"]'
    );
    unreadItems.forEach(item => item.removeAttribute('data-unread'));

    const badge = document.querySelector<HTMLElement>('swp-notification-badge');
    if (badge) {
      badge.style.display = 'none';
    }
  }

  private getDrawer(name: DrawerName): HTMLElement | null {
    switch (name) {
      case 'profile': return this.profileDrawer;
      case 'notification': return this.notificationDrawer;
      case 'todo': return this.todoDrawer;
      case 'newTodo': return this.newTodoDrawer;
    }
  }

  private setupListeners(): void {
    // Profile drawer triggers
    document.getElementById('profileTrigger')
      ?.addEventListener('click', () => this.openProfile());
    document.getElementById('drawerClose')
      ?.addEventListener('click', () => this.close('profile'));

    // Notification drawer triggers
    document.getElementById('notificationsBtn')
      ?.addEventListener('click', () => this.openNotification());
    document.getElementById('notificationDrawerClose')
      ?.addEventListener('click', () => this.close('notification'));
    document.getElementById('markAllRead')
      ?.addEventListener('click', () => this.markAllNotificationsRead());

    // Todo drawer triggers
    document.getElementById('openTodoDrawer')
      ?.addEventListener('click', () => this.openTodo());
    document.getElementById('todoDrawerBack')
      ?.addEventListener('click', () => this.closeTodo());

    // New todo drawer triggers
    document.getElementById('addTodoBtn')
      ?.addEventListener('click', () => this.openNewTodo());
    document.getElementById('newTodoDrawerBack')
      ?.addEventListener('click', () => this.closeNewTodo());
    document.getElementById('cancelNewTodo')
      ?.addEventListener('click', () => this.closeNewTodo());
    document.getElementById('saveNewTodo')
      ?.addEventListener('click', () => this.closeNewTodo());

    // Overlay click closes all
    this.overlay?.addEventListener('click', () => this.closeAll());

    // Escape key closes all
    document.addEventListener('keydown', (e: KeyboardEvent) => {
      if (e.key === 'Escape') this.closeAll();
    });

    // Todo interactions
    this.todoDrawer?.addEventListener('click', (e) => this.handleTodoClick(e));

    // Visibility options
    document.addEventListener('click', (e) => this.handleVisibilityClick(e));
  }

  private handleTodoClick(e: Event): void {
    const target = e.target as HTMLElement;
    const todoItem = target.closest<HTMLElement>('swp-todo-item');
    const checkbox = target.closest<HTMLElement>('swp-todo-checkbox');

    if (checkbox && todoItem) {
      const isCompleted = todoItem.dataset.completed === 'true';
      if (isCompleted) {
        todoItem.removeAttribute('data-completed');
      } else {
        todoItem.dataset.completed = 'true';
      }
    }

    // Toggle section collapse
    const sectionHeader = target.closest<HTMLElement>('swp-todo-section-header');
    if (sectionHeader) {
      const section = sectionHeader.closest<HTMLElement>('swp-todo-section');
      section?.classList.toggle('collapsed');
    }
  }

  private handleVisibilityClick(e: Event): void {
    const target = e.target as HTMLElement;
    const option = target.closest<HTMLElement>('swp-visibility-option');

    if (option) {
      document.querySelectorAll<HTMLElement>('swp-visibility-option')
        .forEach(o => o.classList.remove('active'));
      option.classList.add('active');
    }
  }

  /**
   * Setup generic drawer triggers and close buttons
   * Uses data-drawer-trigger="drawer-id" and data-drawer-close attributes
   */
  private setupGenericDrawers(): void {
    // Handle drawer triggers
    document.addEventListener('click', (e: Event) => {
      const target = e.target as HTMLElement;
      const trigger = target.closest<HTMLElement>('[data-drawer-trigger]');

      if (trigger) {
        const drawerId = trigger.dataset.drawerTrigger;
        if (drawerId) {
          this.openGenericDrawer(drawerId);
        }
      }
    });

    // Handle drawer close buttons
    document.addEventListener('click', (e: Event) => {
      const target = e.target as HTMLElement;
      const closeBtn = target.closest<HTMLElement>('[data-drawer-close]');

      if (closeBtn) {
        this.closeGenericDrawer();
        this.overlay?.classList.remove('active');
        document.body.style.overflow = '';
      }
    });
  }
}
