import { Injectable } from '@angular/core';
import { OrderItemsContext } from './order-items.context';
import { ActionHandler, CommandService } from '@core/command';
import { KulturpassOrderModalService } from '@modal/kulturpass-order';
import { DisplayOrderItemSubsetDTO, OrderItemListItemDTO, ReceiptDTO } from '@generated/swagger/oms-api';
import { DomainReceiptService } from '../receipt.service';
import { DomainGoodsService } from '../goods.service';
import { map } from 'rxjs/operators';

@Injectable()
export class ShopWithKulturpassActionHandler extends ActionHandler<OrderItemsContext> {
  constructor(
    private _modal: KulturpassOrderModalService,
    private _receiptService: DomainReceiptService,
    private _goodsService: DomainGoodsService,
  ) {
    super('SHOP_WITH_KULTURPASS');
  }

  async handler(data: OrderItemsContext, service: CommandService): Promise<OrderItemsContext> {
    const items: OrderItemListItemDTO[] = [];
    const receipts: ReceiptDTO[] = [];

    let command: string;
    for (const item of data.items) {
      const result = await this._modal.open({ orderItemListItem: item, order: data.order }).afterClosed$.toPromise();

      if (result.data == null) {
        return data;
      }

      const displayOrder = result.data[0];
      command = result.data[1];

      if (displayOrder) {
        const subsetItems = displayOrder.items.reduce(
          (acc, item) => [...acc, ...item.subsetItems],
          [] as DisplayOrderItemSubsetDTO[],
        );

        const orderItems = await this.getItems(displayOrder.orderNumber);

        items.push(...orderItems);

        const subsetItemIds = subsetItems.map((item) => item.id);

        const r = await this.getReceipts(subsetItemIds);

        receipts.push(...r);
      }
    }

    if (!command) {
      return {
        ...data,
        items,
        receipts,
      };
    } else {
      return service.handleCommand(command, {
        ...data,
        items,
        receipts,
      });
    }
  }

  getReceipts(ids: number[]) {
    return this._receiptService
      .getReceipts({
        receiptType: 128,
        eagerLoading: 1,
        ids,
      })
      .pipe(map((res) => res.result.map((data) => data.item3.data).filter((data) => !!data)))
      .toPromise();
  }

  getItems(orderNumber: string) {
    return this._goodsService
      .getWarenausgabeItemByOrderNumber(orderNumber, false)
      .pipe(map((res) => res.result))
      .toPromise();
  }
}
