import { inject, Injectable } from '@angular/core';
import {
  AbholfachService,
  DBHOrderItemListItemDTO,
  QueryTokenDTO,
} from '@generated/swagger/oms-api';
import { ResponseArgsError, takeUntilAborted } from '@isa/common/data-access';
import { logger } from '@isa/core/logging';
import { firstValueFrom } from 'rxjs';

/**
 * Service for fetching open reward distribution tasks (Prämienausgabe) from the OMS API.
 *
 * Provides cached access to unfinished reward orders with automatic request deduplication.
 * These are reward orders in processing statuses 16 (Bestellt) and 8192 (Nachbestellt)
 * that need to be completed.
 */
@Injectable({ providedIn: 'root' })
export class OpenRewardTasksService {
  #logger = logger(() => ({ service: 'OpenRewardTasksService' }));
  #abholfachService = inject(AbholfachService);

  /**
   * Fetches open reward distribution tasks (unfinished Prämienausgabe orders).
   *
   * Returns reward orders that are:
   * - In status 16 (Bestellt) or 8192 (Nachbestellt)
   * - Flagged as reward items (praemie: "1-")
   *
   * Results are cached for 1 minute to balance freshness with performance.
   * Cache is automatically invalidated on refresh.
   *
   * @param abortSignal Optional abort signal for request cancellation
   * @returns Promise resolving to array of open reward tasks
   * @throws ResponseArgsError if the API call fails
   */
  async getOpenRewardTasks(
    abortSignal?: AbortSignal,
  ): Promise<DBHOrderItemListItemDTO[]> {
    this.#logger.debug('Fetching open reward tasks');

    const payload: QueryTokenDTO = {
      input: {},
      filter: {
        orderitemprocessingstatus: '16;8192', // Bestellt(16) and Nachbestellt(8192)
        praemie: '1-', // Reward items only
        supplier_id: '16',
      },
      orderBy: [],
    };

    let req$ = this.#abholfachService.AbholfachWarenausgabe(payload);

    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 open reward tasks', error);
      throw error;
    }

    const tasks = res.result ?? [];

    this.#logger.debug('Open reward tasks fetched', () => ({
      taskCount: tasks.length,
    }));

    return tasks;
  }
}
