import { ChangeDetectionStrategy, ChangeDetectorRef, Component, computed, inject, input, output, signal } from '@angular/core';
import { FAST_KENDO_COMMON } from '../../app.config';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

type ToggleType = 'basic' | 'allow-deny' | 'show-hide' | 'combine-separate';

@Component({
  selector: 'fast-toggle',
  imports: [FAST_KENDO_COMMON],
  providers: [{
    provide: NG_VALUE_ACCESSOR,
    multi: true,
    useExisting: FastToggleComponent
  }],
  template: `
  <kendo-switch
  [onLabel]="onLabel()"
  [offLabel]="offLabel()"
  [checked]="isTrue"
  [disabled]="isDisabled()"
  [checked]="checked()"
  [class]="conditionalClasses()"
  (valueChange)="onValueChange($event)">
  </kendo-switch>
  `,
  styles: `:host { @apply flex; }`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class FastToggleComponent implements ControlValueAccessor {
  type = input<ToggleType>('basic');
  onLabel = input<string>();
  offLabel = input<string>();
  isTrue: boolean = false;
  disabled = input<boolean>(false);
  checked = input<boolean>(false);
  valueChange = output<boolean>();

  cdr = inject(ChangeDetectorRef);

  // Internal signal to track form control disabled state
  private formControlDisabled = signal<boolean>(false);

  // Computed signal that combines input disabled state and form control disabled state
  isDisabled = computed(() => this.disabled() || this.formControlDisabled());

  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  onChange = (isTrue: boolean) => { };
  onTouched = () => { };

  writeValue(isTrue: boolean): void {
    this.isTrue = isTrue;
    this.cdr.markForCheck();
  }

  registerOnChange(fn: (value: boolean) => void) {
    this.onChange = fn;
  }

  registerOnTouched(fn: () => void) {
    this.onTouched = fn;
  }

  onValueChange(isTrue: boolean) {
    this.isTrue = isTrue;
    this.onChange(isTrue);
    this.onTouched(); // Mark as touched when value changes
    this.valueChange.emit(isTrue);
  }

  setDisabledState(isDisabled: boolean) {
    this.formControlDisabled.set(isDisabled);
    this.cdr.markForCheck();
  }

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

    classes.push(...this.getCommonClasses());
    if (!this.isDisabled()) {
      classes.push(...this.getLightBaseClasses(this.type()));
      classes.push(...this.getDarkBaseClasses(this.type()));
    }

    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 [
      "text-xs",
      "flex",
      "grow",
      "w-14",
      "h-7.5",
      "whitespace-nowrap",
      "transition-none",
      "focus:ring-4",
      "focus:ring-offset-2",
      "focus:outline-0",
      "[&_.k-switch_span.k-switch-track]:content-start",
      "[&_.k-switch_span.k-switch-track]:items-center",
      "[&_.k-switch-label-on]:left-2",
      "[&_.k-switch-label-on]:inline",
      "[&_.k-switch-label-off]:right-2",
      "[&_.k-switch-label-off]:inline",
      "[&_.k-switch-label-off]:items-end",
      "[&_.k-switch-thumb]:bg-white",
      "[&_.k-switch-thumb]:w-6",
      "[&_.k-switch-thumb]:h-6",
      "[&_.k-switch-track]:w-14",
      "[&_.k-switch-track]:h-7.5",
      "[&.k-switch-off_.k-switch-thumb-wrap]:left-[15px]",
      "[&.k-switch-on_.k-switch-thumb-wrap]:left-[calc(100%-15px)]",
      "[&_.k-switch-thumb-wrap]:w-0",
      "[&_.k-switch-thumb-wrap]:h-0",
      "[&_.k-switch-thumb-wrap]:overflow-visible",
      "[&_.k-switch-thumb-wrap]:absolute",
      "[&_.k-switch-thumb-wrap]:transition-all",
      "[&_.k-switch-thumb-wrap]:duration-200",
      "[&_.k-switch-thumb-wrap]:ease-in-out",
      "[&_.k-switch-thumb-wrap]:top-1/2",
    ];
  }

  getLightBaseClasses(type: ToggleType) {
    const lightBase = [
      "text-base-black-1000",
      "[&_.k-switch-track]:border-2",
      "[&_.k-switch-track]:border-base-gray-500",];
    if (type === 'allow-deny') {
      lightBase.push(
        "[&.k-switch-off_.k-switch-track]:bg-gradient-to-b",
        "[&.k-switch-off_.k-switch-track]:from-base-white-250",
        "[&.k-switch-off_.k-switch-track]:via-red-400",
        "[&.k-switch-off_.k-switch-track]:to-red-300",
        "[&.k-switch-on_.k-switch-track]:bg-gradient-to-b",
        "[&.k-switch-on_.k-switch-track]:from-base-white-250",
        "[&.k-switch-on_.k-switch-track]:via-green-400",
        "[&.k-switch-on_.k-switch-track]:to-green-300",
        "ring-base-gray-750/50");
    }
    else {
      lightBase.push(
        "[&.k-switch-off_.k-switch-track]:bg-gradient-to-b",
        "[&.k-switch-off_.k-switch-track]:from-base-white-1000",
        "[&.k-switch-off_.k-switch-track]:via-base-white-1000",
        "[&.k-switch-off_.k-switch-track]:to-to-base-white-250",
        "[&.k-switch-on_.k-switch-track]:bg-gradient-to-b",
        "[&.k-switch-on_.k-switch-track]:from-base-blue-1000",
        "[&.k-switch-on_.k-switch-track]:via-base-blue-1000",
        "[&.k-switch-on_.k-switch-track]:to-base-blue-250",
        "ring-base-gray-750/50"
      );
    }
    return lightBase;
  }

  getDarkBaseClasses(type: ToggleType) {
    const darkBase = [
      "dark:text-base-white-500",
      "dark:[&_.k-switch-track]:border-alt-blue-250",];
    if (type === 'allow-deny') {
      darkBase.push(
        "dark:[&.k-switch-off_.k-switch-track]:bg-gradient-to-b",
        "dark:[&.k-switch-off_.k-switch-track]:from-alt-gray-250",
        "dark:[&.k-switch-off_.k-switch-track]:via-red-700",
        "dark:[&.k-switch-off_.k-switch-track]:to-red-600",
        "dark:[&.k-switch-on_.k-switch-track]:bg-gradient-to-b",
        "dark:[&.k-switch-on_.k-switch-track]:from-alt-gray-250",
        "dark:[&.k-switch-on_.k-switch-track]:via-green-700",
        "dark:[&.k-switch-on_.k-switch-track]:to-green-600",
        "dark:ring-base-gray-750/50");
    }
    else {
      darkBase.push(
        "dark:[&.k-switch-off_.k-switch-track]:bg-gradient-to-b",
        "dark:[&.k-switch-off_.k-switch-track]:from-alt-gray-1000",
        "dark:[&.k-switch-off_.k-switch-track]:via-alt-gray-1000",
        "dark:[&.k-switch-off_.k-switch-track]:to-alt-gray-500",
        "dark:[&.k-switch-on_.k-switch-track]:bg-gradient-to-b",
        "dark:[&.k-switch-on_.k-switch-track]:from-base-blurple-500",
        "dark:[&.k-switch-on_.k-switch-track]:via-base-blurple-500",
        "dark:[&.k-switch-on_.k-switch-track]:to-alt-blue-250",
        "dark:ring-base-gray-750/50");
    }
    return darkBase;
  }
}
