import { inject, Injectable } from '@angular/core';
import { ActionHandler } from '@core/command';
import { OrderItemsContext } from './order-items.context';
import { OMSPrintService } from '@generated/swagger/print-api';
import { UiModalService } from '@ui/modal';
import { PrintModalComponent, PrintModalData } from '@modal/printer';
import { Group, groupBy } from '@ui/common';
import { DomainPrinterService, Printer } from '@domain/printer';
import { firstValueFrom } from 'rxjs';
import { EnvironmentService } from '@core/environment';
import { ReceiptDTO, ResponseArgs } from '@generated/swagger/oms-api';

@Injectable()
export class PrintSmallamountinvoiceActionHandler extends ActionHandler<OrderItemsContext> {
  private uiModal = inject(UiModalService);
  private omsPrintService = inject(OMSPrintService);
  private _environmentSerivce = inject(EnvironmentService);
  private _domainPrinterService = inject(DomainPrinterService);

  constructor() {
    super('PRINT_SMALLAMOUNTINVOICE');
  }

  private _printKleinbetragsrechnungHelper(
    printer: string,
    receiptGroup: Group<string, ReceiptDTO>,
  ): Promise<ResponseArgs> {
    return firstValueFrom(
      this.omsPrintService.OMSPrintKleinbetragsrechnung({
        data: receiptGroup?.items?.map((r) => r?.id),
        printer,
      }),
    );
  }

  async handler(data: OrderItemsContext): Promise<OrderItemsContext> {
    const printerList = await firstValueFrom(this._domainPrinterService.getAvailableLabelPrinters());
    let printer: Printer;

    if (Array.isArray(printerList)) {
      printer = printerList.find((printer) => printer.selected === true);
    }

    if (!printer || this._environmentSerivce.matchTablet()) {
      await firstValueFrom(
        this.uiModal.open({
          content: PrintModalComponent,
          config: { showScrollbarY: false },
          data: {
            printImmediately: !this._environmentSerivce.matchTablet(),
            printerType: 'Label',
            print: async (printer) => {
              try {
                const receipts = data?.receipts?.filter((r) => r?.receiptType & 128);
                for (const group of groupBy(receipts, (receipt) => receipt?.buyer?.buyerNumber)) {
                  await this._printKleinbetragsrechnungHelper(printer, group);
                }
                return {
                  error: false,
                };
              } catch (error) {
                console.error(error);
                return {
                  error: true,
                  message: error?.message || error,
                };
              }
            },
          } as PrintModalData,
        }).afterClosed$,
      );
    } else {
      const receipts = data?.receipts?.filter((r) => r?.receiptType & 128);
      for (const group of groupBy(receipts, (receipt) => receipt?.buyer?.buyerNumber)) {
        await this._printKleinbetragsrechnungHelper(printer.key, group);
      }
    }
    return data;
  }
}
