import { Component, ChangeDetectionStrategy, OnInit, ElementRef, ViewChild, Renderer2, AfterViewInit, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ApplicationService } from '@core/application';
import { AuthService } from '@core/auth';
import { EnvironmentService } from '@core/environment';
import { provideComponentStore } from '@ngrx/component-store';
import { BranchSelectorComponent } from '@shared/components/branch-selector';
import { BreadcrumbComponent } from '@shared/components/breadcrumb';
import { BranchDTO } from '@generated/swagger/checkout-api';
import { UiErrorModalComponent, UiModalService } from '@ui/modal';
import { Observable, Subject, fromEvent } from 'rxjs';
import { first, map, switchMap, takeUntil, withLatestFrom } from 'rxjs/operators';
import { CustomerOrderSearchStore } from './customer-order-search';
import { provideCancelSearchSubject } from '@shared/services/cancel-subject';

@Component({
  selector: 'page-customer-order',
  templateUrl: 'customer-order.component.html',
  styleUrls: ['customer-order.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  providers: [provideComponentStore(CustomerOrderSearchStore), provideCancelSearchSubject()],
  standalone: false,
})
export class CustomerOrderComponent implements OnInit, AfterViewInit, OnDestroy {
  @ViewChild(BreadcrumbComponent, { read: ElementRef }) breadcrumbRef: ElementRef<HTMLElement>;
  @ViewChild(BranchSelectorComponent, { read: ElementRef }) branchSelectorRef: ElementRef<HTMLElement>;
  processId$ = this._activatedRoute.data.pipe(map((data) => String(data.processId)));

  selectedBranch$: Observable<BranchDTO>;

  get branchSelectorWidth() {
    return `${this.breadcrumbRef?.nativeElement?.clientWidth}px`;
  }

  _onDestroy$ = new Subject<void>();

  get isTablet$() {
    return this._environmentService.matchTablet$;
  }

  constructor(
    public application: ApplicationService,
    private _activatedRoute: ActivatedRoute,
    private _uiModal: UiModalService,
    private _renderer: Renderer2,
    private _environmentService: EnvironmentService,
    public auth: AuthService,
    private _store: CustomerOrderSearchStore,
  ) {}

  ngOnInit(): void {
    this.selectedBranch$ = this.application.activatedProcessId$.pipe(
      switchMap((processId) => this.application.getSelectedBranch$(Number(processId))),
    );

    /* Ticket #4544 - Suchrequest abbrechen bei Prozesswechsel
    / um zu verhindern, dass die Suche in einen anderen Kundenbestellungen Prozess übernommen wird 
    / bei Prozesswechsel zwischen 2 Kundenbestellungen Prozessen
    */
    this.processId$.pipe(takeUntil(this._onDestroy$)).subscribe((processId) => {
      if (Number(processId) !== this._store.processId) {
        this._store.cancelSearchRequest();
      }
    });
  }

  ngAfterViewInit(): void {
    fromEvent(this.branchSelectorRef.nativeElement, 'focusin')
      .pipe(takeUntil(this._onDestroy$), withLatestFrom(this.isTablet$))
      .subscribe(([_, isTablet]) => {
        if (isTablet) {
          this._renderer.setStyle(this.branchSelectorRef?.nativeElement, 'width', this.branchSelectorWidth);
        }
      });

    fromEvent(this.branchSelectorRef.nativeElement, 'focusout')
      .pipe(takeUntil(this._onDestroy$))
      .subscribe((_) => {
        this._renderer.removeStyle(this.branchSelectorRef?.nativeElement, 'width');
      });
  }

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

  async patchProcessData(selectedBranch: BranchDTO) {
    try {
      const processId = await this.application.activatedProcessId$.pipe(first()).toPromise();
      this.application.patchProcessData(Number(processId), { selectedBranch });
    } catch (error) {
      this._uiModal.open({
        title: 'Fehler beim aktualisieren der Daten des Prozesses',
        content: UiErrorModalComponent,
        data: error,
        config: { showScrollbarY: false },
      });
    }
  }
}
