import { Component, ChangeDetectionStrategy, inject, Output, EventEmitter } from '@angular/core';
import { Filter, FilterModule } from '@shared/components/filter';
import { PickupShelfDetailsStore, PickupShelfStore } from '../../store';
import { AsyncPipe } from '@angular/common';
import { EnvironmentService } from '@core/environment';
import { map } from 'rxjs/operators';
import { ActivatedRoute, RouterLink } from '@angular/router';
import { PickUpShelfOutNavigationService, PickupShelfInNavigationService } from '@shared/services/navigation';
import { IconModule } from '@shared/components/icon';
import { UiSpinnerModule } from '@ui/spinner';
import { Observable } from 'rxjs';

@Component({
  selector: 'page-pickup-shelf-filter',
  templateUrl: 'pickup-shelf-filter.component.html',
  styleUrls: ['pickup-shelf-filter.component.css'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  host: { class: 'page-pickup-shelf-filter' },
  imports: [FilterModule, AsyncPipe, RouterLink, IconModule, UiSpinnerModule],
})
export class PickupShelfFilterComponent {
  store = inject(PickupShelfStore);
  detailsStore = inject(PickupShelfDetailsStore);

  filter$ = this.store.filter$;

  get sideOutlet() {
    return this._activatedRoute?.parent?.children?.find((childRoute) => childRoute?.outlet === 'side')?.snapshot
      ?.routeConfig?.path;
  }

  get primaryOutlet() {
    return this._activatedRoute?.parent?.children?.find((childRoute) => childRoute?.outlet === 'primary')?.snapshot
      ?.routeConfig?.path;
  }

  fetching$: Observable<boolean> = this.store.fetchingList$;

  searchboxHint$ = this.store.searchboxHint$;

  get showFilterClose$() {
    return this._environment.matchDesktopLarge$.pipe(map((matches) => !(matches && this.sideOutlet === 'search')));
  }

  get isDesktopLarge() {
    return this._environment.matchDesktopLarge();
  }

  get hasProcessId$() {
    return this._activatedRoute?.parent?.params?.pipe(map((params) => !!params?.processId));
  }

  get order() {
    return this.detailsStore?.order;
  }

  get closeShelfFilterRoute$(): Observable<any[]> {
    return this._activatedRoute?.parent?.params?.pipe(
      map((params) => {
        const hasProcessId = !!params?.processId;

        // Ticket #4457 only route to details view if in split-screen
        if (!!this.order && this.isDesktopLarge) {
          return this._routeToShelfDetails(hasProcessId);
        }

        if (this.sideOutlet === 'search') {
          return this._routeToShelfSearch(hasProcessId);
        }

        return this._routeToShelfList(hasProcessId);
      }),
    );
  }

  @Output() showFilter = new EventEmitter<void>();

  constructor(
    private _environment: EnvironmentService,
    private _activatedRoute: ActivatedRoute,
    private _shelfOutNavigation: PickUpShelfOutNavigationService,
    private _shelfInNavigation: PickupShelfInNavigationService,
  ) {}

  private _routeToShelfSearch(hasProcessId: boolean): any[] {
    if (hasProcessId) {
      return this._shelfOutNavigation.defaultRoute({ processId: this.store.processId }).path;
    } else {
      return this._shelfInNavigation.defaultRoute().path;
    }
  }

  private _routeToShelfList(hasProcessId: boolean): any[] {
    if (hasProcessId) {
      return this._shelfOutNavigation.listRoute({ processId: this.store.processId }).path;
    } else {
      return this._shelfInNavigation.listRoute().path;
    }
  }

  private _routeToShelfDetails(hasProcessId: boolean): any[] {
    const orderId = this.order?.id;
    const orderNumber = this.order?.orderNumber;
    const compartmentCode = this.detailsStore?.compartmentCode;
    const compartmentInfo = this.detailsStore?.compartmentInfo;
    const processingStatus = this.detailsStore?.processingStatus;
    const orderItemSubsetId = this.detailsStore?.selectPreviousSelectedOrderItemSubsetId;

    if (hasProcessId) {
      return this._shelfOutNavigation.detailRoute({
        processId: this.store.processId,
        item: {
          orderId,
          orderNumber,
          compartmentCode,
          processingStatus,
          compartmentInfo,
        },
      }).path;
    } else {
      return this._shelfInNavigation.detailRoute({
        item: {
          orderId,
          orderNumber,
          compartmentCode,
          processingStatus,
          orderItemSubsetId,
          compartmentInfo,
        },
      }).path;
    }
  }

  resetFilter() {
    this.store.setQueryParams(undefined);
  }

  applyFilter(filter: Filter) {
    this.store.setQueryParams(filter.getQueryParams());
    this.store.fetchList();
  }

  clearFilter(filter: Filter) {
    const { main_qs } = filter.getQueryParams();
    this.store.setQueryParams({ main_qs });
  }

  hasSelectedOptions(filter: Filter) {
    // Is Query available
    const hasInputOptions = !!filter.input.find(
      (input) => !!input.input.find((fi) => fi.hasFilterInputOptionsSelected()),
    );

    // Are filter or filterChips selected
    const hasFilterOptions = !!filter.filter.find(
      (input) => !!input.input.find((fi) => fi.hasFilterInputOptionsSelected()),
    );
    return hasInputOptions || hasFilterOptions;
  }
}
