import { CommonModule } from '@angular/common';
import { Component, forwardRef, Input } from '@angular/core';
import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
import { NgSelectModule } from '@ng-select/ng-select';
import { catchError, concat, distinctUntilChanged, map, Observable, of, Subject, switchMap, tap } from 'rxjs';
import { CountyResult, GeoResult } from '../../../../../bizmatch-server/src/models/main.model';
import { City } from '../../../../../bizmatch-server/src/models/server.model';
import { GeoService } from '../../services/geo.service';
import { SelectOptionsService } from '../../services/select-options.service';
import { BaseInputComponent } from '../base-input/base-input.component';
import { TooltipComponent } from '../tooltip/tooltip.component';
import { ValidationMessagesService } from '../validation-messages.service';

@Component({
  selector: 'app-validated-county',
  standalone: true,
  imports: [CommonModule, FormsModule, NgSelectModule, TooltipComponent],
  templateUrl: './validated-county.component.html',
  styleUrl: './validated-county.component.scss',
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => ValidatedCountyComponent),
      multi: true,
    },
  ],
})
export class ValidatedCountyComponent extends BaseInputComponent {
  @Input() items;
  @Input() labelClasses: string;
  @Input() state: string;
  @Input() readonly = false;
  counties$: Observable<CountyResult[]>;
  countyLoading = false;
  countyInput$ = new Subject<string>();
  constructor(validationMessagesService: ValidationMessagesService, private geoService: GeoService, public selectOptions: SelectOptionsService) {
    super(validationMessagesService);
  }

  override ngOnInit() {
    super.ngOnInit();
    this.loadCounties();
  }
  onInputChange(event: City): void {
    this.value = event; //{ ...event, longitude: parseFloat(event.longitude), latitude: parseFloat(event.latitude) };
    this.onChange(this.value);
  }
  private loadCounties() {
    this.counties$ = concat(
      of([]), // default items
      this.countyInput$.pipe(
        distinctUntilChanged(),
        tap(() => (this.countyLoading = true)),
        switchMap(term =>
          this.geoService.findCountiesStartingWith(term, this.state ? [this.state] : null).pipe(
            catchError(() => of([])), // empty list on error
            map(counties => counties.map(county => county.name)), // transform the list of objects to a list of city names
            tap(() => (this.countyLoading = false)),
          ),
        ),
      ),
    );
  }
  trackByFn(item: GeoResult) {
    return item.id;
  }
  compareFn = (item, selected) => {
    return item.id === selected.id;
  };
}
