import {
  booleanAttribute,
  ChangeDetectionStrategy,
  Component,
  ContentChildren,
  Input,
  QueryList,
  ViewEncapsulation
} from '@angular/core';
import { EngieTemplateDirective } from '../../directives/engie-template.directive';
import { AccordionActionsComponent } from '../accordion-actions/accordion-actions.component';
import { AccordionActionDirective } from '../accordion-actions/directive/accordion-action.directive';
import { AccordionItemComponent } from '../accordion-item/accordion-item.component';
import { ButtonComponent } from '../button/button.component';
import { IconComponent } from '../icon/icon.component';

@Component({
  selector: 'nj-accordion',
  templateUrl: './accordion.component.html',
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  imports: [
    AccordionItemComponent,
    IconComponent,
    EngieTemplateDirective,
    AccordionActionsComponent,
    ButtonComponent,
    AccordionActionDirective
  ],
  host: {
    '[class]': 'classes'
  }
})
export class AccordionComponent {
  @Input({ transform: booleanAttribute }) noBorder: boolean;
  @Input({ transform: booleanAttribute }) separated: boolean;

  @ContentChildren(AccordionItemComponent) private accordions?: QueryList<AccordionItemComponent>;

  protected get classes() {
    const classes = ['nj-accordion'];

    if (this.noBorder) {
      classes.push('nj-accordion--no-border');
    }

    if (this.separated) {
      classes.push('nj-accordion--separated');
    }

    return classes;
  }

  /**
   * Expand all children items programmatically
   */
  expandAllItems() {
    const openedGroup = new Set<string>();
    this.accordions.forEach((accordion) => {
      // Firefox doesn't currently support grouping accordion items with `name` property.
      // So we replicate the behavior here to have it on all browsers.
      //
      // As explained in the MDN documentation, when the `name` property is set, only the first details
      // element with the `open` property should be opened.
      if (!accordion.name || !openedGroup.has(accordion.name)) {
        accordion.expand();
      } else {
        accordion.collapse();
      }
      if (accordion.name) {
        openedGroup.add(accordion.name);
      }
    });
  }

  /**
   * Collapse all children items programmatically
   */
  collapseAllItems(name?: string) {
    this.accordions.forEach((accordion) => {
      if (name && accordion.name !== name) {
        return;
      }
      accordion.collapse();
    });
  }
}
