import { inject, Injectable } from '@angular/core';
import { OrderService } from '@generated/swagger/oms-api';
import { ResponseArgsError, takeUntilAborted } from '@isa/common/data-access';
import { logger } from '@isa/core/logging';
import { firstValueFrom } from 'rxjs';
import {
  DBHOrderItemListItem,
  DisplayOrderItemSubset,
  FetchOrderItemSubsetSchema,
  FetchOrderItemSubsetSchemaInput,
  OrderLoyaltyCollectInput,
  OrderLoyaltyCollectSchema,
} from '../schemas';

@Injectable({ providedIn: 'root' })
export class OrderRewardCollectService {
  #logger = logger(() => ({ service: 'OrderRewardCollectService' }));
  #orderService = inject(OrderService);

  async collect(params: OrderLoyaltyCollectInput) {
    try {
      params = OrderLoyaltyCollectSchema.parse(params);
    } catch (error) {
      this.#logger.error('Failed to parse schema', error);
      throw error;
    }

    const req$ = this.#orderService.OrderLoyaltyCollect({
      orderId: params.orderId,
      orderItemId: params.orderItemId,
      orderItemSubsetId: params.orderItemSubsetId,
      data: {
        collectType: params.collectType,
        quantity: params.quantity,
      },
    });

    const res = await firstValueFrom(req$);

    if (res.error) {
      const error = new ResponseArgsError(res);
      this.#logger.error('Failed to collect reward item', error);
      throw error;
    }

    return res.result as DBHOrderItemListItem[];
  }

  async fetchOrderItemSubset(
    params: FetchOrderItemSubsetSchemaInput,
    abortSignal?: AbortSignal,
  ) {
    try {
      params = FetchOrderItemSubsetSchema.parse(params);
    } catch (error) {
      this.#logger.error('Failed to parse schema', error);
      throw error;
    }

    let req$ = this.#orderService.OrderGetOrderItemSubset(
      params.orderItemSubsetId,
    );

    if (abortSignal) {
      req$ = req$.pipe(takeUntilAborted(abortSignal));
    }

    const res = await firstValueFrom(req$);

    if (res.error) {
      const error = new ResponseArgsError(res);
      this.#logger.error('Failed to fetch order item subset', error);
      throw error;
    }

    return res.result as DisplayOrderItemSubset;
  }
}
