/**
 * Application Use Case: UpsertMembershipFeeUseCase
 *
 * Creates or updates membership fee configuration.
 */

import type { IMembershipFeeRepository } from '../../domain/repositories/IMembershipFeeRepository';
import type { MembershipFeeType, MembershipFee } from '../../domain/entities/MembershipFee';
import type {
  IUpsertMembershipFeePresenter,
  UpsertMembershipFeeResultDTO,
  UpsertMembershipFeeViewModel,
} from '../presenters/IUpsertMembershipFeePresenter';
import type { UseCase } from '@core/shared/application/UseCase';

export interface UpsertMembershipFeeInput {
  leagueId: string;
  seasonId?: string;
  type: MembershipFeeType;
  amount: number;
}

export class UpsertMembershipFeeUseCase
  implements UseCase<UpsertMembershipFeeInput, UpsertMembershipFeeResultDTO, UpsertMembershipFeeViewModel, IUpsertMembershipFeePresenter>
{
  constructor(private readonly membershipFeeRepository: IMembershipFeeRepository) {}

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

    const { leagueId, seasonId, type, amount } = input;

    let existingFee = await this.membershipFeeRepository.findByLeagueId(leagueId);
    
    let fee: MembershipFee;
    if (existingFee) {
      existingFee.type = type;
      existingFee.amount = amount;
      existingFee.seasonId = seasonId;
      existingFee.enabled = amount > 0;
      existingFee.updatedAt = new Date();
      fee = await this.membershipFeeRepository.update(existingFee);
    } else {
      const id = `fee-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
      const newFee: MembershipFee = {
        id,
        leagueId,
        seasonId,
        type,
        amount,
        enabled: amount > 0,
        createdAt: new Date(),
        updatedAt: new Date(),
      };
      fee = await this.membershipFeeRepository.create(newFee);
    }

    const dto: UpsertMembershipFeeResultDTO = {
      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,
      },
    };

    presenter.present(dto);
  }
}