import { ChangeDetectionStrategy, Component, forwardRef, inject, input } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { FormFieldContext } from '../form-field/form-field.component';

const HEX_COLOR = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;

@Component({
  selector: 'app-color-picker',
  standalone: true,
  templateUrl: './color-picker.component.html',
  styleUrl: './color-picker.component.scss',
  changeDetection: ChangeDetectionStrategy.OnPush,
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => ColorPickerComponent),
      multi: true
    }
  ]
})
export class ColorPickerComponent implements ControlValueAccessor {
  protected readonly formField = inject(FormFieldContext, { optional: true });

  readonly disabled = input(false);
  readonly ariaLabel = input<string | null>(null);

  protected value = '#000000';
  protected textValue = '#000000';
  protected isDisabled = false;
  protected invalid = false;

  private onChange: (value: string) => void = () => {};
  private onTouched: () => void = () => {};

  writeValue(value: string): void {
    this.value = HEX_COLOR.test(value ?? '') ? value : '#000000';
    this.textValue = value ?? '';
    this.invalid = !HEX_COLOR.test(this.textValue);
  }

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

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

  setDisabledState(isDisabled: boolean): void {
    this.isDisabled = isDisabled;
  }

  protected handleSwatchChange(event: Event): void {
    const target = event.target as HTMLInputElement;
    this.value = target.value;
    this.textValue = target.value;
    this.invalid = false;
    this.onChange(this.value);
  }

  protected handleTextChange(event: Event): void {
    const target = event.target as HTMLInputElement;
    this.textValue = target.value;
    this.invalid = !HEX_COLOR.test(this.textValue);
    if (!this.invalid) {
      this.value = this.textValue;
      this.onChange(this.value);
    }
  }

  protected handleBlur(): void {
    this.onTouched();
  }
}
