/**
 * Application Use Case: GetPaymentsUseCase
 *
 * Retrieves payments based on filters.
 */

import type { IPaymentRepository } from '../../domain/repositories/IPaymentRepository';
import type { Payment, PaymentType } from '../../domain/entities/Payment';
import type { UseCase } from '@core/shared/application/UseCase';
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
import { Result } from '@core/shared/application/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';

export interface GetPaymentsInput {
  leagueId?: string;
  payerId?: string;
  type?: PaymentType;
}

export interface GetPaymentsResult {
  payments: Payment[];
}

export type GetPaymentsErrorCode = never;

export class GetPaymentsUseCase
  implements UseCase<GetPaymentsInput, void, GetPaymentsErrorCode>
{
  constructor(
    private readonly paymentRepository: IPaymentRepository,
    private readonly output: UseCaseOutputPort<GetPaymentsResult>,
  ) {}

  async execute(input: GetPaymentsInput): Promise<Result<void, ApplicationErrorCode<GetPaymentsErrorCode>>> {
    const { leagueId, payerId, type } = input;

    const filters: { leagueId?: string; payerId?: string; type?: PaymentType } = {};
    if (leagueId !== undefined) filters.leagueId = leagueId;
    if (payerId !== undefined) filters.payerId = payerId;
    if (type !== undefined) filters.type = type;

    const payments = await this.paymentRepository.findByFilters(filters);

    this.output.present({ payments });

    return Result.ok(undefined);
  }
}