import { Highlightable } from '@angular/cdk/a11y';
import { NgTemplateOutlet } from '@angular/common';
import { ChangeDetectionStrategy, Component, computed, ElementRef, inject, input, signal, } from '@angular/core';
import { FastTabPanelComponent } from './fast-tabpanel.component';

/**
 * Tab header component that displays the clickable tab label and handles focus management.
 * Implements the Highlightable interface for integration with Angular CDK's keyboard navigation.
 *
 * @example
 * ```html
 * <app-tab-header
 *   [tab]="tabPanel"
 *   [isSelected]="true"
 *   [tabIndex]="0"
 *   [isActive]="false">
 * </app-tab-header>
 * ```
 *
 * Features:
 * - Proper ARIA attributes for accessibility
 * - Focus management integration with KeyManager
 * - Support for custom tab labels via templates
 * - Visual feedback for active and selected states
 */
@Component({
  selector: 'fast-tabheader',
  imports: [NgTemplateOutlet],
  template: `
  @if (tab().headerTemplate(); as headerTemplate) {
  <ng-container [ngTemplateOutlet]="headerTemplate.templateRef"></ng-container>
  } @else {
    {{ tab().label() }}
  }

  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
  styles: ``,
  host: {
    role: 'tab',
    '[class]': 'conditionalClasses()',
    '[class.is-active]': 'enabledTabIndex()',
    '[class.is-selected]': 'isSelected()',
    '[class.aria-disabled]': 'disabledClasses()',
    '[attr.id]': '"tab-" + tabIndex()',
    '[attr.aria-selected]': 'isSelected()',
    '[attr.aria-controls]': '"tabpanel-" + tabIndex()',
    '[attr.tabindex]': 'isActive() ? "0" : "-1"',
    '[attr.aria-disabled]': 'isDisabled()',
  },
})
export class FastTabHeaderComponent implements Highlightable {
  /** Signal to track activation state (not currently used) */
  activate = signal(false);

  /** Reference to the associated tab panel component */
  tab = input.required<FastTabPanelComponent>();

  /** The zero-based index of this tab within the tab group */
  tabIndex = input.required<number>();

  /** Whether this tab header currently has keyboard focus */
  isActive = input(false);

  /** Whether this tab is disabled and cannot be selected */
  isDisabled = input(false);

  disabledClasses = computed(() => {
    this.getConditionalClassesFromArrays([
      "pointer-events-none",
      "cursor-not-allowed",
      "opacity-50"
    ]);
  });

  /**
   * Getter required by the Highlightable interface.
   * Returns the disabled state for compatibility with Angular CDK.
   */
  get disabled(): boolean | undefined {
    return this.isDisabled();
  }

  /** Reference to the native HTML element for direct DOM manipulation */
  element = inject<ElementRef<HTMLElement>>(ElementRef<HTMLElement>)
    .nativeElement;

  /** Signal that controls whether this tab should receive focus */
  enabledTabIndex = signal(false);

  /** Whether this tab is currently selected (shows its content) */
  isSelected = input.required<boolean>();

  /**
   * Called by the KeyManager when this tab becomes the active (focused) item.
   * Enables tabindex and focuses the element for keyboard navigation.
   * Required by the Highlightable interface.
   */
  setActiveStyles(): void {
    this.enabledTabIndex.set(true);
    this.element.focus();
  }

  /**
   * Called by the KeyManager when this tab loses focus.
   * Disables tabindex to remove from tab order.
   * Required by the Highlightable interface.
   */
  setInactiveStyles(): void {
    this.enabledTabIndex.set(false);
  }

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

    classes.push(...this.getCommonClasses());
    classes.push(...this.getLightBaseClasses());
    classes.push(...this.getDarkBaseClasses());
    classes.push(...this.getLightHoverActiveClasses());
    classes.push(...this.getDarkHoverActiveClasses());

    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() {
    return [
      "flex",
      "cursor-pointer",
      "justify-center",
      "px-4",
      "py-3",
      "[&.is-active]:outline-none",
    ];
  }

  getLightBaseClasses() {
    const lightBase = [] as string[];

    lightBase.push(
      "text-base-black-1000",
      "bg-base-white-500",
    )

    return lightBase;
  }

  getDarkBaseClasses() {
    const darkBase = [] as string[];

    darkBase.push(
      "dark:bg-alt-gray-750",
      "dark:text-base-white-500",
    )

    return darkBase;
  }

  getLightHoverActiveClasses() {
    const lightOther = [] as string[];

    lightOther.push(
      "hover:bg-base-blue-500",
      "active:sepia",
      "[&.is-active]:bg-base-blue-750",
      "[&.is-selected]:bg-base-blue-750",
      "[&.is-active]:ring-1",
      "[&.is-active]:ring-base-gray-1000",
    )

    return lightOther;
  }

  getDarkHoverActiveClasses() {
    const darkOther = [] as string[];

    darkOther.push(
      "dark:hover:bg-base-blurple-500",
      "dark:active:sepia",
      "dark:[&.is-active]:bg-base-blurple-250",
      "dark:[&.is-selected]:bg-base-blurple-250",
      "[&.is-active]:ring-1",
      "[&.is-active]:ring-alt-white-1000",
    )

    return darkOther;
  }
}
