import { _IdGenerator } from '@angular/cdk/a11y';
import { CdkAccordionItem } from '@angular/cdk/accordion';
import { ChangeDetectionStrategy, Component, computed, inject, input, output, } from '@angular/core';
import { FastSVGComponent } from './fast-svg.component';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';

@Component({
  selector: 'fast-panelbar-item',
  imports: [FastSVGComponent],
  template: `
      <h3 role="heading">
      <button
        class="peer flex w-full cursor-pointer items-center focus-visible:outline-1 focus-visible:outline-offset-4 focus-visible:outline-ring disabled:text-disabled-foreground aria-expanded:font-medium p-3
        bg-base-white-500
        dark:bg-alt-gray-500"
        (click)="onToggle()"
        [disabled]="disabled"
        [attr.aria-expanded]="expanded"
        [id]="accordionTriggerId"
        [attr.aria-controls]="accordionBodyId"
      >
        <div class="font-bold text-sm
        bg-base-white-500
        dark:bg-alt-gray-500">
          {{ title() }}
        </div>
        <fast-svg
          [class.rotate-180]="expanded"
          class="ml-auto transition-transform"
          icon="chevronDown"
          />
      </button>
    </h3>
    @if (expanded) {
      <div
        role="region"
        [id]="accordionBodyId"
        [attr.aria-labelledby]="accordionTriggerId"
        class="px-4.5 pt-1
        bg-base-white-500
        dark:bg-alt-gray-500"
      >
        <ng-content></ng-content>
      </div>
    }
  `,
  styles: ``,
  changeDetection: ChangeDetectionStrategy.OnPush,
  host: {
    '[class]': 'conditionalClasses()',
  },
})
export class FastPanelbarItemComponent extends CdkAccordionItem {
  title = input<string>();
  panelId = input<string>();
  accordionBodyId = inject(_IdGenerator).getId('accordion-item-body-');
  accordionTriggerId = inject(_IdGenerator).getId('accordion-item-trigger-');

  expand = output<FastPanelbarItemComponent>();
  collapse = output<FastPanelbarItemComponent>();
  // eslint-disable-next-line @angular-eslint/no-output-native
  select = output<FastPanelbarItemComponent>();

  constructor() {
    super();
    // check with the original accordion methods and follow it until component is destroyed
    this.opened
      .pipe(takeUntilDestroyed())
      .subscribe(() => this.expand.emit(this));

    this.closed
      .pipe(takeUntilDestroyed())
      .subscribe(() => this.collapse.emit(this));
  }

  onToggle() {
    this.select.emit(this);
    this.toggle();
  }

  conditionalClasses = computed(() => {
    const classes = [] as string[];

    classes.push(...this.getCommonClasses());
    classes.push(...this.getLightBaseClasses());
    classes.push(...this.getDarkBaseClasses());
    if (!this.disabled) {
      classes.push(...this.getLightHoverClasses());
      classes.push(...this.getDarkHoverClasses());
    }

    const conditionalClasses = this.getConditionalClassesFromArrays(classes);
    return conditionalClasses;
  });

  getConditionalClassesFromArrays(classArray: string[]): { [key: string]: boolean } {
    const classes: { [key: string]: boolean } = {};
    classArray.forEach(className => {
      classes[className] = true;
    });
    return classes;
  }

  getCommonClasses() {
    const commonClasses = [] as string[];
    commonClasses.push(
      "flex",
      "flex-col",
      "not-last:m-1.5",
      "not-last:mb-0",
      "not-last:border-b",
      "not-last:border-global-bar-light",
      "last:m-1.5",
      "last-mt-0",
      "group",
    );
    return commonClasses;
  }

  getLightBaseClasses() {
    const lightBase = [
      "bg-base-white-500",
      "text-base-black-1000",
      "border-base-black-1000"]

    return lightBase;
  }

  getDarkBaseClasses() {
    const darkBase = [
      "dark:bg-alt-gray-500",
      "dark:text-base-white-500",
      "dark:border-base-white-250"]
    return darkBase;
  }

  getLightHoverClasses() {
    const lightHover = [
      "bg-base-white-1000",
    ];
    return lightHover;
  }

  getDarkHoverClasses() {
    const darkHover = [
      "dark:bg-alt-gray-750",
    ];
    return darkHover;
  }
}
