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, Observable, of, Subject, switchMap, tap } from 'rxjs';
import { 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-city',
  standalone: true,
  imports: [CommonModule, FormsModule, NgSelectModule, TooltipComponent],
  templateUrl: './validated-city.component.html',
  styleUrl: './validated-city.component.scss',
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => ValidatedCityComponent),
      multi: true,
    },
  ],
})
export class ValidatedCityComponent extends BaseInputComponent {
  @Input() items;
  @Input() labelClasses: string;
  @Input() state: string;
  cities$: Observable<GeoResult[]>;
  cityInput$ = new Subject<string>();
  countyInput$ = new Subject<string>();
  cityLoading = false;
  constructor(validationMessagesService: ValidationMessagesService, private geoService: GeoService, public selectOptions: SelectOptionsService) {
    super(validationMessagesService);
  }

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