import { Injectable } from '@angular/core';
import { Actions, ofType, createEffect, ROOT_EFFECTS_INIT, OnInitEffects } from '@ngrx/effects';

import * as actions from './details.actions';
import { flatMap, catchError, map, debounceTime, throttleTime } from 'rxjs/operators';
import { OrderService, StrictHttpResponse, ListResponseArgsOfOrderItemListItemDTO, AbholfachService } from '@swagger/oms';
import { of, NEVER, interval } from 'rxjs';
import { SearchStateFacade } from '../search';

@Injectable()
export class DetailsEffects implements OnInitEffects {
  constructor(
    private actions$: Actions,
    private abholfachService: AbholfachService,
    private orderService: OrderService,
    private searchStateFacade: SearchStateFacade
  ) {}

  fetchOrderItemsByOrderNumber$ = createEffect(() =>
    this.actions$.pipe(
      ofType(actions.fetchDetailsByOrderNumber),
      flatMap((a) =>
        this.abholfachService
          .AbholfachWarenausgabeResponse({
            filter: { all_branches: 'true' },
            input: {
              qs: a.orderNumber,
            },
          })
          .pipe(catchError((err) => of<StrictHttpResponse<ListResponseArgsOfOrderItemListItemDTO>>(err)))
      ),
      map((response) => actions.fetchDetailsByOrderNumberDone({ response }))
    )
  );

  fetchOrderItemsByCompartmentCode$ = createEffect(() =>
    this.actions$.pipe(
      ofType(actions.fetchDetailsByCompartmentCode),
      flatMap((a) =>
        this.abholfachService
          .AbholfachWarenausgabeResponse({
            filter: { all_branches: 'true' },
            input: {
              qs: a.compartmentCode,
            },
          })
          .pipe(catchError((err) => of<StrictHttpResponse<ListResponseArgsOfOrderItemListItemDTO>>(err)))
      ),
      map((response) => actions.fetchDetailsByCompartmentCodeDone({ response }))
    )
  );

  fetchOrderItemsByOrderItemIds$ = createEffect(() =>
    this.actions$.pipe(
      ofType(actions.fetchDetailsOrderItemIds),
      flatMap((a) =>
        this.abholfachService
          .AbholfachWarenausgabeResponse({
            ids: a.orderItemIds,
            filter: { all_branches: 'true' },
            input: { qs: '' },
          })
          .pipe(catchError((err) => of<StrictHttpResponse<ListResponseArgsOfOrderItemListItemDTO>>(err)))
      ),
      map((response) => actions.fetchDetailsOrderItemIdsDone({ response }))
    )
  );

  fetchOrderItemsByOrderItemSubsetIds$ = createEffect(() =>
    this.actions$.pipe(
      ofType(actions.fetchDetailsOrderItemSubsetIds),
      flatMap((a) =>
        this.abholfachService
          .AbholfachWarenausgabeResponse({
            ids: a.orderItemSubsetIds,
            filter: { all_branches: 'true' },
            input: { qs: '' },
          })
          .pipe(catchError((err) => of<StrictHttpResponse<ListResponseArgsOfOrderItemListItemDTO>>(err)))
      ),
      map((response) => actions.fetchDetailsOrderItemSubsetIdsDone({ response }))
    )
  );

  fetchOrderItemsDone$ = createEffect(() =>
    this.actions$.pipe(
      ofType(
        actions.fetchDetailsByOrderNumberDone,
        actions.fetchDetailsByCompartmentCodeDone,
        actions.fetchDetailsOrderItemSubsetIdsDone,
        actions.fetchDetailsByOrderNumberDone
      ),
      flatMap((a) => {
        if (a.response.ok) {
          this.searchStateFacade.reloadResults();
          return [actions.addOrderItems({ orderItems: a.response.body.result })];
        }
        return NEVER;
      })
    )
  );

  setComment$ = createEffect(() =>
    this.actions$.pipe(
      ofType(actions.patchComment),
      flatMap((a) =>
        this.orderService.OrderPatchOrderItemSubsetResponse({
          orderId: a.orderId,
          orderItemId: a.orderItemId,
          orderItemSubsetId: a.orderItemSubsetId,
          orderItemSubset: {
            specialComment: a.comment,
          },
        })
      ),
      map((response) => actions.patchCommentDone({ response }))
    )
  );

  setCommentDone$ = createEffect(() =>
    this.actions$.pipe(
      ofType(actions.patchCommentDone),
      flatMap(({ response }) => {
        if (response.ok) {
          const result = response.body.result;
          this.searchStateFacade.reloadResults();
          return [
            actions.setComment({
              orderItemSubsetId: result.id,
              comment: result.specialComment,
            }),
          ];
        }
        return NEVER;
      })
    )
  );

  ngrxOnInitEffects() {
    return actions.cleanup();
  }
}
