import { Component, ChangeDetectionStrategy, OnInit, OnDestroy, inject } from '@angular/core';
import { ComponentStore } from '@ngrx/component-store';
import { tapResponse } from '@ngrx/operators';

import { HistoryDTO } from '@generated/swagger/crm-api';
import { Observable, Subject, combineLatest } from 'rxjs';
import { map, switchMap, takeUntil, tap } from 'rxjs/operators';
import { CustomerSearchStore } from '../store';
import { CustomerSearchNavigation } from '@shared/services/navigation';
import { AsyncPipe } from '@angular/common';
import { IconModule } from '@shared/components/icon';
import { SharedHistoryListModule } from '@shared/components/history';
import { ActivatedRoute, RouterLink } from '@angular/router';
import { DomainOmsService } from '@domain/oms';

export interface CustomerHistoryViewMainState {
  history?: HistoryDTO[];
  fetching?: boolean;
}

@Component({
  selector: 'page-customer-order-details-history-main-view',
  templateUrl: 'order-details-history-main-view.component.html',
  styleUrls: ['order-details-history-main-view.component.css'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [AsyncPipe, RouterLink, IconModule, SharedHistoryListModule],
})
export class CustomerOrderDetailsHistoryMainViewComponent
  extends ComponentStore<CustomerHistoryViewMainState>
  implements OnInit, OnDestroy
{
  private _activvatedRoute = inject(ActivatedRoute);
  private _store = inject(CustomerSearchStore);
  private _omsService = inject(DomainOmsService);
  private _navigation = inject(CustomerSearchNavigation);

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

  fetching$ = this.select((s) => s.fetching);

  history$ = this.select((s) => s.history);

  processId$ = this._store.processId$;

  customerId$ = this._store.customerId$;

  customer$ = this._store.customer$;

  customerName$ = this.customer$.pipe(map((customer) => `${customer?.lastName}, ${customer?.firstName}`));

  customerNumber$ = this.customer$.pipe(map((customer) => customer?.customerNumber));

  orderId$ = this._activvatedRoute.params.pipe(map((params) => Number(params.orderId)));

  order$ = this._store.order$;

  orderItemId$ = this._activvatedRoute.params.pipe(map((params) => Number(params.orderItemId)));

  orderItemSubsetId$ = combineLatest([this.order$, this.orderItemId$]).pipe(
    map(([order, orderItemId]) => order?.items?.find((item) => item.id === orderItemId)?.data?.subsetItems?.[0]?.id),
  );

  detailsRoute$ = combineLatest([this.processId$, this.customerId$, this.orderId$, this.orderItemId$]).pipe(
    map(([processId, customerId, orderId, orderItemId]) =>
      this._navigation.orderDetialsRoute({ processId, customerId, orderId, orderItemId }),
    ),
  );

  constructor() {
    super({});
  }

  ngOnInit(): void {
    this.orderId$.pipe(takeUntil(this._onDestroy$)).subscribe((orderId) => {
      this._store.selectOrder(orderId);
    });

    this.orderItemSubsetId$.pipe(takeUntil(this._onDestroy$)).subscribe((orderItemSubsetId) => {
      if (orderItemSubsetId) {
        this.fetchHistory(orderItemSubsetId);
      }
    });
  }

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

  fetchHistory = this.effect((orderItemSubsetId$: Observable<number>) =>
    orderItemSubsetId$.pipe(
      tap(() => this.patchState({ fetching: true })),
      switchMap((orderItemSubsetId) =>
        this._omsService
          .getHistory(orderItemSubsetId)
          .pipe(
            tapResponse(this.handleFetchHistoryResponse, this.handleFetchHistoryError, this.handleFetchHistoryComplete),
          ),
      ),
    ),
  );

  handleFetchHistoryResponse = (history: HistoryDTO[]) => {
    this.patchState({ history });
  };

  handleFetchHistoryError = (err: any) => {
    console.error(err);
  };

  handleFetchHistoryComplete = () => {
    this.patchState({ fetching: false });
  };
}
