import { ChangeDetectorRef, Injectable, OnDestroy, Pipe, PipeTransform } from '@angular/core';
import { CountryDTO } from '@swagger/crm';
import { CrmCustomerService } from '@domain/crm';
import { BehaviorSubject, combineLatest } from 'rxjs';
import { debounceTime } from 'rxjs/operators';

@Pipe({
  name: 'country',
  pure: false,
})
export class CountryPipe implements PipeTransform, OnDestroy {
  private result: string;

  private inputValue = new BehaviorSubject<any>(undefined);
  private inputKey = new BehaviorSubject<keyof CountryDTO>(undefined);
  private displayKey = new BehaviorSubject<keyof CountryDTO>(undefined);

  private countrySubscription = combineLatest([this.inputValue, this.inputKey, this.displayKey, this.customerService.getCountries()])
    .pipe(debounceTime(1))
    .subscribe(([value, inputKey, displayKey, countries]) => {
      let nextResult = this.result;

      if (!!value && countries?.result?.length > 0) {
        const country = countries.result.find((c) => c[inputKey] === value);

        if (country && nextResult !== country[displayKey]) {
          nextResult = String(country[displayKey]);
        }
      } else {
        nextResult = undefined;
      }

      if (nextResult !== this.result) {
        this.result = nextResult;
        this.cdr.markForCheck();
      }
    });

  constructor(private customerService: CrmCustomerService, private cdr: ChangeDetectorRef) {}

  transform(value: any, inputKey: keyof CountryDTO = 'isO3166_A_3', displayKey: keyof CountryDTO = 'name'): string {
    if (this.inputValue.value !== value) {
      this.inputValue.next(value);
    }

    if (this.inputKey.value !== inputKey) {
      this.inputKey.next(inputKey);
    }

    if (this.displayKey.value !== displayKey) {
      this.displayKey.next(displayKey);
    }

    return this.result;
  }

  ngOnDestroy() {
    this.countrySubscription.unsubscribe();
    this.inputValue.complete();
    this.inputKey.complete();
    this.displayKey.complete();
  }
}
