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

@Injectable()
export class PrintShippingNoteActionHandler extends ActionHandler<OrderItemsContext> {
  private uiModal = inject(UiModalService);
  private domainPrinterService = inject(DomainPrinterService);
  private _environmentSerivce = inject(EnvironmentService);

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

  async printShippingNoteHelper(printer: string, receipts: ReceiptDTO[]) {
    try {
      for (const group of groupBy(
        receipts,
        (receipt) => receipt?.buyer?.buyerNumber,
      )) {
        await this.domainPrinterService
          .printShippingNote({
            printer,
            receipts: group?.items?.map((r) => r?.id),
          })
          .toPromise();
      }
      return {
        error: false,
      };
    } catch (error) {
      console.error(error);
      return {
        error: true,
        message: error?.message || error,
      };
    }
  }

  async handler(data: OrderItemsContext): Promise<OrderItemsContext> {
    const printerList = await this.domainPrinterService
      .getAvailableLabelPrinters()
      .toPromise();
    const receipts = data?.receipts?.filter((r) => r?.receiptType & 1);
    let printer: Printer;

    if (Array.isArray(printerList)) {
      printer = printerList.find((printer) => printer.selected === true);
    }
    if (!printer || this._environmentSerivce.matchTablet()) {
      await this.uiModal
        .open({
          content: PrintModalComponent,
          config: { showScrollbarY: false },
          data: {
            printImmediately: !this._environmentSerivce.matchTablet(),
            printerType: 'Label',
            print: async (printer) =>
              await this.printShippingNoteHelper(printer, receipts),
          } as PrintModalData,
        })
        .afterClosed$.toPromise();
    } else {
      await this.printShippingNoteHelper(printer.key, receipts);
    }

    return data;
  }
}
