import {
  Component,
  forwardRef,
  inject,
  input,
  linkedSignal,
  model,
  signal,
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import {
  DropdownButtonComponent,
  DropdownAppearance,
  DropdownFilterComponent,
  DropdownOptionComponent,
} from '@isa/ui/input-controls';
import { Branch, BranchesResource } from '@isa/checkout/data-access';
import { logger } from '@isa/core/logging';

@Component({
  selector: 'checkout-branch-dropdown',
  templateUrl: 'branch-dropdown.component.html',
  styleUrls: ['branch-dropdown.component.css'],
  imports: [
    DropdownButtonComponent,
    DropdownFilterComponent,
    DropdownOptionComponent,
  ],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => BranchDropdownComponent),
      multi: true,
    },
  ],
})
export class BranchDropdownComponent implements ControlValueAccessor {
  #logger = logger({ component: 'BranchDropdownComponent' });
  #branchesResource = inject(BranchesResource).resource;

  readonly DropdownAppearance = DropdownAppearance;

  readonly appearance = input<DropdownAppearance>(
    DropdownAppearance.AccentOutline,
  );

  readonly selected = model<Branch | null>(null);
  readonly disabled = signal(false);

  readonly options = linkedSignal<Branch[]>(() =>
    this.#branchesResource.hasValue() ? this.#branchesResource.value() : [],
  );

  readonly equals = (a: Branch | null, b: Branch | null) => a?.id === b?.id;

  #onChange?: (value: Branch | null) => void;
  #onTouched?: () => void;

  writeValue(value: Branch | null): void {
    this.#logger.debug('writeValue', () => ({ branchId: value?.id }));
    this.selected.set(value);
  }

  registerOnChange(fn: (value: Branch | null) => void): void {
    this.#onChange = fn;
  }

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

  setDisabledState(isDisabled: boolean): void {
    this.#logger.debug('setDisabledState', () => ({ isDisabled }));
    this.disabled.set(isDisabled);
  }

  onSelectionChange(branch: Branch | undefined): void {
    const value = branch ?? null;
    this.#logger.debug('Selection changed', () => ({ branchId: value?.id }));
    this.selected.set(value);
    this.#onChange?.(value);
    this.#onTouched?.();
  }
}
