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

import type { IMembershipFeeRepository, IMemberPaymentRepository } from '../../domain/repositories/IMembershipFeeRepository';
import type {
  IGetMembershipFeesPresenter,
  GetMembershipFeesResultDTO,
  GetMembershipFeesViewModel,
} from '../presenters/IGetMembershipFeesPresenter';
import type { UseCase } from '@core/shared/application/UseCase';

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

export class GetMembershipFeesUseCase
  implements UseCase<GetMembershipFeesInput, GetMembershipFeesResultDTO, GetMembershipFeesViewModel, IGetMembershipFeesPresenter>
{
  constructor(
    private readonly membershipFeeRepository: IMembershipFeeRepository,
    private readonly memberPaymentRepository: IMemberPaymentRepository,
  ) {}

  async execute(
    input: GetMembershipFeesInput,
    presenter: IGetMembershipFeesPresenter,
  ): Promise<void> {
    presenter.reset();

    const { leagueId, driverId } = input;

    if (!leagueId) {
      throw new Error('leagueId is required');
    }

    const fee = await this.membershipFeeRepository.findByLeagueId(leagueId);
    
    let payments: unknown[] = [];
    if (driverId && fee) {
      const memberPayments = await this.memberPaymentRepository.findByLeagueIdAndDriverId(leagueId, driverId, this.membershipFeeRepository);
      payments = memberPayments.map(p => ({
        id: p.id,
        feeId: p.feeId,
        driverId: p.driverId,
        amount: p.amount,
        platformFee: p.platformFee,
        netAmount: p.netAmount,
        status: p.status,
        dueDate: p.dueDate,
        paidAt: p.paidAt,
      }));
    }

    const dto: GetMembershipFeesResultDTO = {
      fee: fee ? {
        id: fee.id,
        leagueId: fee.leagueId,
        seasonId: fee.seasonId,
        type: fee.type,
        amount: fee.amount,
        enabled: fee.enabled,
        createdAt: fee.createdAt,
        updatedAt: fee.updatedAt,
      } : null,
      payments,
    };

    presenter.present(dto);
  }
}