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

import type { UseCase } from '@core/shared/application/UseCase';
import { Result } from '@core/shared/domain/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { Prize, PrizeType } from '../../domain/entities/Prize';
import type { PrizeRepository } from '../../domain/repositories/PrizeRepository';

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

export interface CreatePrizeResult {
  prize: Prize;
}

export type CreatePrizeErrorCode = 'PRIZE_ALREADY_EXISTS';

export class CreatePrizeUseCase
  implements UseCase<CreatePrizeInput, CreatePrizeResult, CreatePrizeErrorCode>
{
  constructor(
    private readonly prizeRepository: PrizeRepository,
  ) {}

  async execute(input: CreatePrizeInput): Promise<Result<CreatePrizeResult, ApplicationErrorCode<CreatePrizeErrorCode>>> {
    const { leagueId, seasonId, position, name, amount, type, description } = input;

    const existingPrize = await this.prizeRepository.findByPosition(leagueId, seasonId, position);
    if (existingPrize) {
      return Result.err({ code: 'PRIZE_ALREADY_EXISTS' as const });
    }

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

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

    return Result.ok({ prize: createdPrize });
  }
}