/**
 * Accordion Controller
 *
 * Generic accordion component with smooth expand/collapse animations.
 * Supports single-open behavior (only one item expanded at a time).
 */

export interface AccordionOptions {
  /** Only allow one item to be expanded at a time (default: true) */
  singleOpen?: boolean;
  /** Animation duration for expand in ms (default: 250) */
  expandDuration?: number;
  /** Animation duration for collapse in ms (default: 200) */
  collapseDuration?: number;
}

export class Accordion {
  private container: HTMLElement;
  private singleOpen: boolean;
  private expandDuration: number;
  private collapseDuration: number;

  constructor(selector: string | HTMLElement, options: AccordionOptions = {}) {
    // Get container element
    if (typeof selector === 'string') {
      const el = document.querySelector<HTMLElement>(selector);
      if (!el) {
        console.warn(`Accordion: Element not found for selector "${selector}"`);
        return;
      }
      this.container = el;
    } else {
      this.container = selector;
    }

    // Set options with defaults
    this.singleOpen = options.singleOpen ?? true;
    this.expandDuration = options.expandDuration ?? 250;
    this.collapseDuration = options.collapseDuration ?? 200;

    this.setupEventListeners();
  }

  /**
   * Setup click listeners on accordion headers
   */
  private setupEventListeners(): void {
    const headers = this.container.querySelectorAll<HTMLElement>('swp-accordion-header');

    headers.forEach(header => {
      header.addEventListener('click', (e) => {
        // Don't toggle if clicking on interactive elements
        const target = e.target as HTMLElement;
        if (target.closest('input, button, a, select')) return;

        const item = header.closest<HTMLElement>('swp-accordion-item');
        if (item) {
          this.toggle(item);
        }
      });
    });
  }

  /**
   * Toggle an accordion item
   */
  toggle(item: HTMLElement): void {
    const isExpanded = item.classList.contains('expanded');

    if (isExpanded) {
      this.collapse(item);
    } else {
      // Close other items first if single-open mode
      if (this.singleOpen) {
        this.container.querySelectorAll<HTMLElement>('swp-accordion-item.expanded').forEach(otherItem => {
          if (otherItem !== item) {
            this.collapse(otherItem);
          }
        });
      }
      this.expand(item);
    }
  }

  /**
   * Expand an accordion item with animation
   */
  expand(item: HTMLElement): void {
    const content = item.querySelector<HTMLElement>('swp-accordion-content');
    const toggle = item.querySelector<HTMLElement>('swp-accordion-toggle');

    if (!content) return;

    // Add expanded class immediately for CSS to show content
    item.classList.add('expanded');

    // Animate toggle icon rotation
    toggle?.animate([
      { transform: 'rotate(0deg)' },
      { transform: 'rotate(180deg)' }
    ], {
      duration: this.expandDuration,
      easing: 'ease-out',
      fill: 'forwards'
    });

    // Animate content height
    const height = content.scrollHeight;
    content.animate([
      { height: '0px', opacity: 0 },
      { height: `${height}px`, opacity: 1 }
    ], {
      duration: this.expandDuration,
      easing: 'ease-out',
      fill: 'forwards'
    });
  }

  /**
   * Collapse an accordion item with animation
   */
  collapse(item: HTMLElement): void {
    const content = item.querySelector<HTMLElement>('swp-accordion-content');
    const toggle = item.querySelector<HTMLElement>('swp-accordion-toggle');

    if (!content) return;

    // Animate toggle icon rotation
    toggle?.animate([
      { transform: 'rotate(180deg)' },
      { transform: 'rotate(0deg)' }
    ], {
      duration: this.collapseDuration,
      easing: 'ease-out',
      fill: 'forwards'
    });

    // Animate content height
    const height = content.scrollHeight;
    const animation = content.animate([
      { height: `${height}px`, opacity: 1 },
      { height: '0px', opacity: 0 }
    ], {
      duration: this.collapseDuration,
      easing: 'ease-out',
      fill: 'forwards'
    });

    // Remove expanded class after animation completes
    animation.onfinish = () => {
      item.classList.remove('expanded');
    };
  }

  /**
   * Expand all items (only useful when singleOpen is false)
   */
  expandAll(): void {
    this.container.querySelectorAll<HTMLElement>('swp-accordion-item:not(.expanded)').forEach(item => {
      this.expand(item);
    });
  }

  /**
   * Collapse all items
   */
  collapseAll(): void {
    this.container.querySelectorAll<HTMLElement>('swp-accordion-item.expanded').forEach(item => {
      this.collapse(item);
    });
  }

  /**
   * Get all expanded items
   */
  getExpanded(): HTMLElement[] {
    return Array.from(this.container.querySelectorAll<HTMLElement>('swp-accordion-item.expanded'));
  }
}

/**
 * Initialize all accordions on the page
 */
export function initAccordions(options: AccordionOptions = {}): Accordion[] {
  const accordions: Accordion[] = [];
  document.querySelectorAll<HTMLElement>('swp-accordion').forEach(container => {
    accordions.push(new Accordion(container, options));
  });
  return accordions;
}
