import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { map, switchMap, filter, tap, shareReplay } from 'rxjs/operators';
import { LocationService } from './location-service';
import { RemissionOverlayService } from '../../modules/remission/services';
import { Select } from '@ngxs/store';

import { ShelfOverlayService } from '../../modules/shelf/services';
import { RemissionSelectors } from '../store/selectors/remission.selectors';
import { SharedSelectors } from '../store/selectors/shared.selectors';
import { SearchStateFacade } from '../../store/customer';
import { isNullOrUndefined } from 'util';

@Injectable({ providedIn: 'root' })
export class ContentHeaderService {
  @Select(RemissionSelectors.getRemissionActiveFilters)
  remissionFilters$: Observable<string[]>;
  @Select(SharedSelectors.getActiveModule)
  activeModule$: Observable<{ id: number; name: 'Customer' | 'Branch' }>;

  whiteList = {
    breadcrumbs: [],
    filter: ['/remission/create', '/remission/started', '/shelf'],
  };
  blackList = {
    breadcrumbs: ['/dashboard', '/branch/main'],
    filter: ['/history', 'edit'],
  };

  constructor(
    private locationService: LocationService,
    private searchStore: SearchStateFacade,
    private remissionOverlayService: RemissionOverlayService,
    private shelfOverlayService: ShelfOverlayService
  ) {}

  get showBreadcrumbs$(): Observable<boolean> {
    return this.locationService.currentPath$.pipe(this.shouldShowBreadcrumbs);
  }

  get showFilter$(): Observable<boolean> {
    return this.locationService.currentPath$.pipe(this.shouldShowFilter);
  }

  get isFilterActive$(): Observable<boolean> {
    return this.locationService.url$.pipe(
      filter((url) => !isNullOrUndefined(url)),
      switchMap((activeSection) => {
        if (activeSection.includes('remission')) {
          return this.remissionFilters$.pipe(map((selectedFilters) => selectedFilters && !!Object.entries(selectedFilters).length));
        }

        if (activeSection.includes('shelf')) {
          return this.searchStore.hasActiveFilters$;
        }

        return of(false);
      }),
      shareReplay()
    );
  }

  get module$(): Observable<'Customer' | 'Branch'> {
    return this.activeModule$.pipe(map((module) => module.name));
  }

  get activeSection$(): Observable<'remission' | 'shelf'> {
    return of(this.locationService.url).pipe(
      map((url) => {
        if (url.includes('remission')) {
          return 'remission';
        }

        if (url.includes('shelf')) {
          return 'shelf';
        }
      })
    );
  }

  toggleFilter() {
    return this.activeSection$
      .pipe(
        map((activeSection) => {
          switch (activeSection) {
            case 'remission':
              this.remissionOverlayService.openRemissionListFilter();
              break;

            case 'shelf':
              this.shelfOverlayService.openShelfFilter();
              break;
          }
        })
      )
      .toPromise();
  }

  shouldShowBreadcrumbs = (url: Observable<string>): Observable<boolean> => {
    return url.pipe(map((path) => this.isAllowed('breadcrumbs', path)));
  };

  shouldShowFilter = (url: Observable<string>): Observable<boolean> => {
    return url.pipe(map((path) => this.isAllowed('filter', path)));
  };

  private isAllowed(type: 'breadcrumbs' | 'filter', url: string): boolean {
    const applicableWhitelist = this.whiteList[type];
    const applicableBlacklist = this.blackList[type];

    if (type === 'filter') {
      const isOnWhiteList = !!applicableWhitelist.find((whitelistetUrl) => whitelistetUrl.includes(url) || url.includes(whitelistetUrl));
      const isOnBlacklist = applicableBlacklist.find((blackListUrl) => blackListUrl.includes(url) || url.includes(blackListUrl));
      return isOnWhiteList && !isOnBlacklist;
    }

    if (type === 'breadcrumbs') {
      const isOnBlackList = !!applicableBlacklist.find((blacklistetUrl) => blacklistetUrl.includes(url) || url.includes(blacklistetUrl));
      return !isOnBlackList;
    }
  }
}
