import { Injectable, inject } from '@angular/core';
import { CommandService } from '@core/command';
import { DomainReceiptService, OrderItemsContext } from '@domain/oms';
import {
  DBHOrderItemListItemDTO,
  KeyValueDTOOfStringAndString,
  OrderDTO,
  ReceiptDTO,
  ReceiptType,
} from '@generated/swagger/oms-api';
import { catchError, map } from 'rxjs/operators';

@Injectable()
export class ActionHandlerService {
  private commandService = inject(CommandService);

  private domainReceiptService = inject(DomainReceiptService);

  constructor() {}

  async handle(data: {
    action: KeyValueDTOOfStringAndString;
    items: DBHOrderItemListItemDTO[];
    compartmentCode?: string;
    compartmentInfo?: string;
    itemQuantity?: Map<number, number>;
    order?: OrderDTO;
  }): Promise<OrderItemsContext> {
    let receipts: ReceiptDTO[] = [];
    if (data.action.command.includes('PRINT_SHIPPINGNOTE') || data.action.command === 'PRINT_SMALLAMOUNTINVOICE') {
      receipts = await this.loadReceipts({ orderItemSubsetIds: data.items.map((i) => i.orderItemSubsetId) });
    }

    // #2737 Bei Zubuchen kein Abholfachzettel ausdrucken
    let command = data.action.command;
    if (data.compartmentCode) {
      command = data.action.command.replace('|PRINT_COMPARTMENTLABEL', '');
    }

    const context: OrderItemsContext = {
      items: data.items,
      compartmentCode: data.compartmentCode,
      compartmentInfo: data.compartmentInfo,
      itemQuantity: data.itemQuantity,
      order: data.order,
      receipts,
    };

    return this.commandService.handleCommand(command, context);
  }

  loadReceipts({ orderItemSubsetIds }: { orderItemSubsetIds: number[] }): Promise<ReceiptDTO[]> {
    return this.domainReceiptService
      .getReceipts({
        eagerLoading: 1,
        receiptType: (1 + 64 + 128) as ReceiptType,
        ids: orderItemSubsetIds,
      })
      .pipe(
        map((res) => res.result.map((r) => r.item3?.data).filter((f) => !!f)),
        catchError(() => []),
      )
      .toPromise();
  }
}
