import { Injectable } from '@angular/core';
import { map, withLatestFrom, tap, first, filter } from 'rxjs/operators';
import { TabSelectionOptions } from '@libs/ui/lib/tab-selection';
import { Observable, of, BehaviorSubject, combineLatest } from 'rxjs';
import { RemissionSourceType, RemissionSupplier, RemissionProcess } from '@isa/remission';
import { Store, Select } from '@ngxs/store';
import { RemissionSelectors } from '../../../core/store/selectors/remission.selectors';
import { RequestUpdateRemissionFilter } from '../../../core/store/actions/remission.actions';
import { RemissionSourcesDisplayPipe } from '../../../pipes/remission-sources-display.pipe';
import { RemissionProcessStatuses } from '../../../core/models/remission-process-statuses.model';
import { RemissionResourceType } from '../models/remission-resource-type.model';

@Injectable({ providedIn: 'root' })
export class RemissionTabsFilterService {
  @Select(RemissionSelectors.getRemissionProcess) remissionProcess$: Observable<RemissionProcess>;
  @Select(RemissionSelectors.getRemissiontarget) activeSupplier$: Observable<string>;
  @Select(RemissionSelectors.getRemissionSource) activeSource$: Observable<RemissionResourceType>;
  @Select(RemissionSelectors.getRemissionProcessStatuses)
  remissionProcessStatuses$: Observable<RemissionProcessStatuses>;

  suppliers$ = new BehaviorSubject<RemissionSupplier[]>(null);
  sources$ = new BehaviorSubject<RemissionSourceType[]>(null);

  sourcesDisplayNamePipe: RemissionSourcesDisplayPipe;

  constructor(private store: Store) {
    this.sourcesDisplayNamePipe = new RemissionSourcesDisplayPipe();
  }

  getSupplierTabs(suppliers$: Observable<RemissionSupplier[]>): Observable<TabSelectionOptions> {
    // tslint:disable-next-line: deprecation
    return combineLatest(this.activeSupplier$, suppliers$, this.remissionProcessStatuses$).pipe(
      tap(([_, suppliers]) => this.suppliers$.next(suppliers)),
      filter(([activeSupplier, suppliers, status]) => !!activeSupplier && !!suppliers.length && !!status),
      map(([activeSupplier, suppliers, status]) => {
        return {
          locked: status.started ? true : false,
          options: suppliers.map((supplier) => ({
            name: supplier.name,
            selected: activeSupplier === supplier.name,
          })),
        };
      })
    );
  }

  getSourcesTabs(sources$: Observable<RemissionSourceType[]>): Observable<TabSelectionOptions> {
    // tslint:disable-next-line: deprecation
    return combineLatest(this.activeSource$, sources$).pipe(
      tap(([_, sources]) => this.sources$.next(sources)),
      filter(([activeSource, sources]) => !!activeSource && !!sources.length),
      map(([activeSource, sources]) => {
        return {
          locked: false,
          options: sources.map((source) => ({
            name: source,
            selected: activeSource === source,
            displayName: this.sourcesDisplayNamePipe.transform(source),
          })),
        };
      })
    );
  }

  setActiveSource(name: string) {
    this.sources$
      .pipe(
        map((sources) => sources.find((source) => source === name)),
        withLatestFrom(this.remissionProcess$.pipe(map((process) => process.id))),
        first()
      )
      .subscribe(([source, remissionProcessId]) =>
        this.store.dispatch(
          new RequestUpdateRemissionFilter(remissionProcessId, {
            source,
            skip: 0,
          })
        )
      );
  }

  setActiveSupplier(name: string) {
    this.suppliers$
      .pipe(
        map((suppliers) => suppliers.find((supplier) => supplier.name === name)),
        withLatestFrom(this.remissionProcess$.pipe(map((process) => process.id))),
        first(),
        withLatestFrom(this.activeSource$)
      )
      .subscribe(([[supplier, remissionProcessId], source]) =>
        this.store.dispatch(
          new RequestUpdateRemissionFilter(remissionProcessId, {
            source,
            target: supplier,
            skip: 0,
          })
        )
      );
  }
}
