import type { ISeasonRepository } from '../../domain/repositories/ISeasonRepository';
import type { ILeagueRepository } from '../../domain/repositories/ILeagueRepository';
import { Result } from '@core/shared/application/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { UseCaseOutputPort } from '@core/shared/application';
import type { Season } from '../../domain/entities/season/Season';

export type GetSeasonDetailsInput = {
  leagueId: string;
  seasonId: string;
};

export type GetSeasonDetailsResult = {
  leagueId: Season['leagueId'];
  season: Season;
};

export type GetSeasonDetailsErrorCode =
  | 'LEAGUE_NOT_FOUND'
  | 'SEASON_NOT_FOUND'
  | 'REPOSITORY_ERROR';

/**
 * GetSeasonDetailsUseCase
 */
export class GetSeasonDetailsUseCase {
  constructor(
    private readonly leagueRepository: ILeagueRepository,
    private readonly seasonRepository: ISeasonRepository,
    private readonly output: UseCaseOutputPort<GetSeasonDetailsResult>,
  ) {}

  async execute(
    input: GetSeasonDetailsInput,
  ): Promise<
    Result<void, ApplicationErrorCode<GetSeasonDetailsErrorCode, { message: string }>>
  > {
    try {
      const league = await this.leagueRepository.findById(input.leagueId);
      if (!league) {
        return Result.err({
          code: 'LEAGUE_NOT_FOUND',
          details: { message: `League not found: ${input.leagueId}` },
        });
      }

      const season = await this.seasonRepository.findById(input.seasonId);
      if (!season || season.leagueId.toString() !== league.id.toString()) {
        return Result.err({
          code: 'SEASON_NOT_FOUND',
          details: {
            message: `Season ${input.seasonId} does not belong to league ${league.id}`,
          },
        });
      }

      const result: GetSeasonDetailsResult = {
        leagueId: league.id.toString(),
        season,
      };

      this.output.present(result);

      return Result.ok(undefined);
    } catch (error: unknown) {
      const message =
        error && typeof (error as Error).message === 'string'
          ? (error as Error).message
          : 'Failed to load season details';

      return Result.err({
        code: 'REPOSITORY_ERROR',
        details: { message },
      });
    }
  }
}