import { HttpErrorResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { ActionHandler, CommandService } from '@core/command';
import { ReorderModalComponent, ReorderResult } from '@modal/reorder';
import { AvailabilityDTO2, OrderItemListItemDTO } from '@swagger/oms';
import { UiModalService } from '@ui/modal';
import { isResponseArgs } from '@utils/object';
import { first } from 'rxjs/operators';
import { DomainOmsService } from '../oms.service';
import { OrderItemsContext } from './order-items.context';

@Injectable()
export class OrderAtSupplierActionHandler extends ActionHandler<OrderItemsContext> {
  constructor(private _command: CommandService, private _domainOmsService: DomainOmsService, private _uiModal: UiModalService) {
    super('ORDER_AT_SUPPLIER');
  }

  async handler(data: OrderItemsContext): Promise<OrderItemsContext> {
    const updatedItems: OrderItemListItemDTO[] = [];
    for (const orderItem of data.items) {
      const result = await this._uiModal
        .open<ReorderResult, { item: OrderItemListItemDTO; showReasons: boolean }>({
          content: ReorderModalComponent,
          title: 'Artikel bestellen',
          data: { item: orderItem, showReasons: false },
        })
        .afterClosed$.toPromise();

      try {
        if (result.data) {
          if (result.data.action === 'REORDER') {
            await this.patchOrderItemSubset(result.data.item, result.data.availability);
            await this.orderAtSupplier(result.data.item);
            updatedItems.push({ ...orderItem, processingStatus: 16 });
          } else if (result.data.action === 'NOTAVAILABLE') {
            let context = { ...data, items: [orderItem] };
            context = await this._command.handleCommand('NOTAVAILABLE', context);
            updatedItems.push(...context.items);
          }
        } else {
          return data;
        }
      } catch (err) {
        if (err instanceof HttpErrorResponse && isResponseArgs(err.error)) {
          console.error('InvalidProperties: ', err.error.invalidProperties);
          console.error('Message: ', err.message);
        } else {
          console.error('Message: ', err.message);
        }
        console.error('OrderAtSupplierActionHandler._domainOmsService.orderAtSupplier', err);
        throw err;
      }
    }

    return { ...data, items: updatedItems };
  }

  async patchOrderItemSubset(orderItem: OrderItemListItemDTO, availability: AvailabilityDTO2) {
    return await this._domainOmsService
      .patchOrderItemSubset({
        orderId: orderItem.orderId,
        orderItemId: orderItem.orderItemId,
        orderItemSubsetId: orderItem.orderItemSubsetId,
        orderItemSubset: {
          ssc: availability.ssc,
          sscText: availability.sscText,
          supplier: {
            id: availability.supplierId,
          },
          isPrebooked: availability.isPrebooked,
          estimatedShippingDate: availability.at,
        },
      })
      .pipe(first())
      .toPromise();
  }

  async orderAtSupplier(orderItem: OrderItemListItemDTO) {
    return await this._domainOmsService
      .orderAtSupplier({
        orderId: orderItem.orderId,
        orderItemId: orderItem.orderItemId,
        orderItemSubsetId: orderItem.orderItemSubsetId,
      })
      .pipe(first())
      .toPromise();
  }
}
