/**
 * Application Use Case: GetMembershipFeesUseCase
 *
 * Retrieves membership fees and member payments.
 */

import type { IMembershipFeeRepository, IMemberPaymentRepository } from '../../domain/repositories/IMembershipFeeRepository';
import type { MembershipFee } from '../../domain/entities/MembershipFee';
import type { MemberPayment } from '../../domain/entities/MemberPayment';
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 type GetMembershipFeesErrorCode = 'INVALID_INPUT';

export interface GetMembershipFeesInput {
  leagueId: string;
  driverId?: string;
}

export interface GetMembershipFeesResult {
  fee: MembershipFee | null;
  payments: MemberPayment[];
}

export class GetMembershipFeesUseCase
  implements UseCase<GetMembershipFeesInput, void, GetMembershipFeesErrorCode>
{
  constructor(
    private readonly membershipFeeRepository: IMembershipFeeRepository,
    private readonly memberPaymentRepository: IMemberPaymentRepository,
    private readonly output: UseCaseOutputPort<GetMembershipFeesResult>,
  ) {}

  async execute(input: GetMembershipFeesInput): Promise<Result<void, ApplicationErrorCode<GetMembershipFeesErrorCode>>> {
    const { leagueId, driverId } = input;

    if (!leagueId) {
      return Result.err({ code: 'INVALID_INPUT' as const });
    }

    const fee = await this.membershipFeeRepository.findByLeagueId(leagueId);

    let payments: MemberPayment[] = [];
    if (driverId && fee) {
      payments = await this.memberPaymentRepository.findByLeagueIdAndDriverId(leagueId, driverId, this.membershipFeeRepository);
    }

    this.output.present({ fee, payments });

    return Result.ok(undefined);
  }
}