import {NgIf, NgIfContext, NgTemplateOutlet} from '@angular/common';
import {
  AfterContentInit,
  booleanAttribute,
  Component,
  ContentChildren,
  ElementRef,
  inject,
  Input,
  QueryList,
  TemplateRef,
  ViewEncapsulation
} from '@angular/core';
import {EngieTemplateDirective} from '../../directives/engie-template.directive';
import {TSizeVariants} from '../../models/size-variant.model';
import {AccordionComponent} from '../accordion/accordion.component';
import {IconComponent} from '../icon/icon.component';

@Component({
  selector: 'details[nj-accordion-item]',
  templateUrl: './accordion-item.component.html',
  styleUrls: ['./accordion-item.component.scss'],
  standalone: true,
  encapsulation: ViewEncapsulation.None,
  imports: [
    IconComponent,
    NgIf,
    NgTemplateOutlet
  ],
  host: {
    '[class]': 'classes',
    '(click)': 'handleClick($event)',
  }
})
export class AccordionItemComponent implements AfterContentInit {

  private element: ElementRef<HTMLDetailsElement> = inject(ElementRef);

  private accordion = inject(AccordionComponent);

  protected iconTemplate?: TemplateRef<unknown>;
  protected headerTemplate?: TemplateRef<NgIfContext<string>>;

  /**
   * Size of the accordion item
   */
  @Input() scale?: Extract<TSizeVariants, 'md' | 'lg'>;

  /**
   * Whether the toggle icon is place at the start of the item or not.
   */
  @Input({transform: booleanAttribute}) hasLeadingToggleIcon?: boolean;

  /**
   * Whether the toggle use the alternative icons (plus/minus) or the default ones (arrow).
   */
  @Input({transform: booleanAttribute}) useAlternativeToggleIcon?: boolean;

  /**
   * This attribute enables multiple <details> elements to be connected, with only one open at a time.
   */
  @Input() name?: string;

  /**
   * Item header
   */
  @Input() label?: string;

  @ContentChildren(EngieTemplateDirective) protected templateDirectives?: QueryList<EngieTemplateDirective>;

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

    if (this.scale && this.scale !== 'md') {
      classes.push(`nj-accordion-item--${this.scale}`);
    }

    if (this.hasLeadingToggleIcon) {
      classes.push('nj-accordion-item--leading-toggle');
    }
    return classes;
  }

  ngAfterContentInit() {
    this.templateDirectives.forEach((templateDirective) => {
      if (templateDirective?.selector === 'icon') {
        this.iconTemplate = templateDirective.templateRef;
      }

      if (templateDirective?.selector === 'header') {
        this.headerTemplate = templateDirective.templateRef as TemplateRef<NgIfContext<string>>;
      }
    });
  }

  protected handleClick(event: MouseEvent) {
    if (this.name && !this.element.nativeElement.open) {
      event.preventDefault();
      this.accordion.collapseAllItems(this.name);
      this.expand();
    }
  }

  /**
   * Expand the accordion item programmatically
   */
  expand() {
    if (this.element) {
      this.element.nativeElement.open = true;
    }
  }

  /**
   * Collapse the accordion item programmatically
   */
  collapse() {
    if (this.element) {
      this.element.nativeElement.open = false;
    }
  }
}
