/**
 * @sc4rfurryx/proteusjs/a11y-primitives
 * Lightweight accessibility patterns
 * 
 * @version 2.0.0
 * @author sc4rfurry
 * @license MIT
 */

export interface Controller {
  destroy(): void;
}

export interface DialogOptions {
  modal?: boolean;
  restoreFocus?: boolean;
}

export interface TooltipOptions {
  delay?: number;
  placement?: 'top' | 'bottom' | 'left' | 'right';
}

export interface FocusTrapController {
  activate(): void;
  deactivate(): void;
}

export function dialog(root: Element | string, opts: DialogOptions = {}): Controller {
  const el = typeof root === 'string' ? document.querySelector(root) : root;
  if (!el) throw new Error('Dialog element not found');

  const { modal = true, restoreFocus = true } = opts;
  let prevFocus: Element | null = null;

  const open = () => {
    if (restoreFocus) prevFocus = document.activeElement;
    el.setAttribute('role', 'dialog');
    if (modal) el.setAttribute('aria-modal', 'true');
    (el as HTMLElement).focus();
  };

  const close = () => {
    if (restoreFocus && prevFocus) (prevFocus as HTMLElement).focus();
  };

  return { destroy: () => close() };
}

export function tooltip(trigger: Element, content: HTMLElement, opts: TooltipOptions = {}): Controller {
  const { delay = 300 } = opts;
  let timeout: number;

  const show = () => {
    clearTimeout(timeout);
    timeout = window.setTimeout(() => {
      content.setAttribute('role', 'tooltip');
      trigger.setAttribute('aria-describedby', content.id || 'tooltip');
      content.style.display = 'block';
    }, delay);
  };

  const hide = () => {
    clearTimeout(timeout);
    content.style.display = 'none';
    trigger.removeAttribute('aria-describedby');
  };

  trigger.addEventListener('mouseenter', show);
  trigger.addEventListener('mouseleave', hide);
  trigger.addEventListener('focus', show);
  trigger.addEventListener('blur', hide);

  return {
    destroy: () => {
      clearTimeout(timeout);
      trigger.removeEventListener('mouseenter', show);
      trigger.removeEventListener('mouseleave', hide);
      trigger.removeEventListener('focus', show);
      trigger.removeEventListener('blur', hide);
    }
  };
}

export function focusTrap(container: Element): FocusTrapController {
  const focusable = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
  
  const activate = () => {
    const elements = container.querySelectorAll(focusable);
    if (elements.length === 0) return;
    
    const first = elements[0] as HTMLElement;
    const last = elements[elements.length - 1] as HTMLElement;
    
    const handleTab = (e: KeyboardEvent) => {
      if (e.key !== 'Tab') return;
      
      if (e.shiftKey && document.activeElement === first) {
        e.preventDefault();
        last.focus();
      } else if (!e.shiftKey && document.activeElement === last) {
        e.preventDefault();
        first.focus();
      }
    };
    
    container.addEventListener('keydown', handleTab as EventListener);
    first.focus();

    return () => container.removeEventListener('keydown', handleTab as EventListener);
  };

  let deactivate = () => {};

  return {
    activate: () => { deactivate = activate() || (() => {}); },
    deactivate: () => deactivate()
  };
}

export function menu(container: Element): Controller {
  const items = container.querySelectorAll('[role="menuitem"]');
  let currentIndex = 0;

  const navigate = (e: KeyboardEvent) => {
    switch (e.key) {
      case 'ArrowDown':
        e.preventDefault();
        currentIndex = (currentIndex + 1) % items.length;
        (items[currentIndex] as HTMLElement).focus();
        break;
      case 'ArrowUp':
        e.preventDefault();
        currentIndex = currentIndex === 0 ? items.length - 1 : currentIndex - 1;
        (items[currentIndex] as HTMLElement).focus();
        break;
      case 'Escape':
        e.preventDefault();
        container.dispatchEvent(new CustomEvent('menu:close'));
        break;
    }
  };

  container.setAttribute('role', 'menu');
  container.addEventListener('keydown', navigate as EventListener);

  return {
    destroy: () => container.removeEventListener('keydown', navigate as EventListener)
  };
}

export default { dialog, tooltip, focusTrap, menu };
