/**
 * Application Use Case: CreatePrizeUseCase
 *
 * Creates a new prize.
 */

import type { IPrizeRepository } from '../../domain/repositories/IPrizeRepository';
import type { PrizeType, Prize } from '../../domain/entities/Prize';
import type {
  ICreatePrizePresenter,
  CreatePrizeResultDTO,
  CreatePrizeViewModel,
} from '../presenters/ICreatePrizePresenter';
import type { UseCase } from '@core/shared/application/UseCase';

export interface CreatePrizeInput {
  leagueId: string;
  seasonId: string;
  position: number;
  name: string;
  amount: number;
  type: PrizeType;
  description?: string;
}

export class CreatePrizeUseCase
  implements UseCase<CreatePrizeInput, CreatePrizeResultDTO, CreatePrizeViewModel, ICreatePrizePresenter>
{
  constructor(private readonly prizeRepository: IPrizeRepository) {}

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

    const { leagueId, seasonId, position, name, amount, type, description } = input;

    const existingPrize = await this.prizeRepository.findByPosition(leagueId, seasonId, position);
    if (existingPrize) {
      throw new Error(`Prize for position ${position} already exists`);
    }

    const id = `prize-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
    const prize: Prize = {
      id,
      leagueId,
      seasonId,
      position,
      name,
      amount,
      type,
      description,
      awarded: false,
      createdAt: new Date(),
    };

    const createdPrize = await this.prizeRepository.create(prize);

    const dto: CreatePrizeResultDTO = {
      prize: {
        id: createdPrize.id,
        leagueId: createdPrize.leagueId,
        seasonId: createdPrize.seasonId,
        position: createdPrize.position,
        name: createdPrize.name,
        amount: createdPrize.amount,
        type: createdPrize.type,
        description: createdPrize.description,
        awarded: createdPrize.awarded,
        awardedTo: createdPrize.awardedTo,
        awardedAt: createdPrize.awardedAt,
        createdAt: createdPrize.createdAt,
      },
    };

    presenter.present(dto);
  }
}