import { Component, ChangeDetectionStrategy, ChangeDetectorRef, OnInit, OnDestroy, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { BreadcrumbService } from '@core/breadcrumb';
import { Observable, Subject } from 'rxjs';
import { map, takeUntil } from 'rxjs/operators';
import { CustomerOrderSearchStore } from '../customer-order-search.store';
import { EnvironmentService } from '@core/environment';
import { ApplicationService } from '@core/application';
import { Filter, FilterComponent } from '@shared/components/filter';
import { CustomerOrdersNavigationService } from '@shared/services/navigation';

@Component({
  selector: 'page-customer-order-search-filter',
  templateUrl: 'customer-order-search-filter.component.html',
  styleUrls: ['customer-order-search-filter.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  standalone: false,
})
export class CustomerOrderSearchFilterComponent implements OnInit, OnDestroy {
  loading$: Observable<boolean>;

  message$ = this._customerOrdersSearchStore.message$;

  processId = Number(this._activatedRoute?.parent?.snapshot?.data?.processId);

  private _onDestroy$ = new Subject<void>();

  @ViewChild(FilterComponent, { static: false })
  uiFilter: FilterComponent;

  filter$: Observable<Filter>;

  get isTablet() {
    return this._environment.matchTablet();
  }

  get isDesktop() {
    return this._environment.matchDesktop();
  }

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

  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;
  }

  get closeFilterRoute() {
    const compartmentCode = this._activatedRoute.snapshot.params.compartmentCode;
    const orderId = this._activatedRoute.snapshot.params.orderId;
    const processingStatus = this._activatedRoute.snapshot.params.processingStatus;
    if (!compartmentCode && !orderId) {
      if (this.sideOutlet === 'search') {
        return this._navigationService.getCustomerOrdersBasePath(this.processId).path;
      } else if (this.primaryOutlet === 'results' || this.sideOutlet === 'results') {
        return this._navigationService.getCustomerOrdersResultsPath(this.processId).path;
      }
    } else {
      return this._navigationService.getCustomerOrdersDetailsPath({
        processId: this.processId,
        processingStatus,
        compartmentCode: compartmentCode ?? undefined,
        orderId: orderId ? Number(orderId) : undefined,
      }).path;
    }
  }

  showFilter: boolean = false;

  constructor(
    private _customerOrdersSearchStore: CustomerOrderSearchStore,
    private _breadcrumb: BreadcrumbService,
    private _cdr: ChangeDetectorRef,
    private _router: Router,
    private _environment: EnvironmentService,
    private _activatedRoute: ActivatedRoute,
    public application: ApplicationService,
    private _navigationService: CustomerOrdersNavigationService,
  ) {}

  ngOnInit() {
    this.showFilter = this.sideOutlet !== 'search';
    this._activatedRoute.queryParams.pipe(takeUntil(this._onDestroy$)).subscribe((queryParams) => {
      this._customerOrdersSearchStore.setQueryParams(queryParams);
    });

    // #4143 To make Splitscreen Search and Filter work combined
    this._customerOrdersSearchStore.searchStarted.pipe(takeUntil(this._onDestroy$)).subscribe(async (_) => {
      let queryParams = {
        ...this._customerOrdersSearchStore?.filter?.getQueryParams(),
        ...this.cleanupQueryParams(this.uiFilter?.uiFilter?.getQueryParams()),
      };

      // Always override query if not in tablet mode
      if (!!this._customerOrdersSearchStore.filter.getQueryParams()?.main_qs && !this.isTablet) {
        queryParams = { ...queryParams, main_qs: this._customerOrdersSearchStore.filter.getQueryParams()?.main_qs };
      }

      this._customerOrdersSearchStore.setQueryParams(queryParams);
    });

    this._customerOrdersSearchStore.searchResultSubject.pipe(takeUntil(this._onDestroy$)).subscribe(async (result) => {
      if (result.results.error) {
      } else {
        if (result.results.hits > 0) {
          const queryParams = this._customerOrdersSearchStore.filter.getQueryParams();
          if (result.results.hits === 1) {
            const orderItem = result.results.result[0];
            await this._navigationService
              .getCustomerOrdersDetailsPath({
                processId: this.processId,
                processingStatus: orderItem?.processingStatus,
                compartmentCode: orderItem?.compartmentCode ? encodeURIComponent(orderItem.compartmentCode) : undefined,
                orderId: orderItem?.orderId ? orderItem.orderId : undefined,
                extras: { queryParams },
              })
              .navigate();
          } else {
            await this._navigationService.getCustomerOrdersResultsPath(this.processId, { queryParams }).navigate();
          }
        } else {
          this._customerOrdersSearchStore.setMessage('keine Suchergebnisse');
        }

        this._cdr.markForCheck();
      }
    });

    this._initSettings();
    this._initLoading$();
  }

  ngOnDestroy() {
    this._onDestroy$.next();
    this._onDestroy$.complete();
  }

  private _initSettings() {
    this.filter$ = this._customerOrdersSearchStore.filter$;
  }

  private _initLoading$() {
    this.loading$ = this._customerOrdersSearchStore.fetching$;
  }

  async resetFilter() {
    this._customerOrdersSearchStore.resetFilter();
    this._initSettings();
    this._cdr.markForCheck();
  }

  async applyFilter(filter: Filter) {
    this.uiFilter?.cancelAutocomplete();
    this._customerOrdersSearchStore.setMessage('');

    const queryParams = filter.getQueryParams();
    this._customerOrdersSearchStore.setQueryParams(queryParams);
    await this.updateQueryParams(queryParams);
    this._customerOrdersSearchStore.search({ clear: true });
  }

  async updateBreadcrumb() {
    await this._breadcrumb.addOrUpdateBreadcrumbIfNotExists({
      key: this.processId,
      name: 'Kundenbestellung',
      path: this._navigationService.getCustomerOrdersBasePath(this.processId).path,
      tags: ['customer-order', 'main', 'filter'],
      section: 'customer',
      params: this._customerOrdersSearchStore.filter?.getQueryParams(),
    });
  }

  async updateQueryParams(queryParams: Record<string, string>) {
    await this._router.navigate([], { queryParams });
    this.updateBreadcrumb();
  }

  cleanupQueryParams(params: Record<string, string> = {}) {
    const clean = { ...params };

    for (const key in clean) {
      if (Object.prototype.hasOwnProperty.call(clean, key)) {
        if (clean[key] == undefined) {
          delete clean[key];
        }
      }
    }

    return clean;
  }

  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;
  }

  clearFilter(value: Filter) {
    value.unselectAllFilterOptions();
  }
}
