import type { Result } from '@core/shared/application/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type {
  GetRaceWithSOFResult,
  GetRaceWithSOFErrorCode,
} from '@core/racing/application/use-cases/GetRaceWithSOFUseCase';
import type { RaceWithSOFDTO } from '../dtos/RaceWithSOFDTO';

export type GetRaceWithSOFResponseModel = RaceWithSOFDTO;

export type GetRaceWithSOFApplicationError = ApplicationErrorCode<
  GetRaceWithSOFErrorCode,
  { message: string }
>;

export class RaceWithSOFPresenter {
  private model: GetRaceWithSOFResponseModel | null = null;

  reset(): void {
    this.model = null;
  }

  present(result: Result<GetRaceWithSOFResult, GetRaceWithSOFApplicationError>): void {
    if (result.isErr()) {
      const error = result.unwrapErr();
      if (error.code === 'RACE_NOT_FOUND') {
        this.model = {
          id: '',
          track: '',
          strengthOfField: null,
        } as RaceWithSOFDTO;
        return;
      }

      throw new Error(error.details?.message ?? 'Failed to get race with SOF');
    }

    const output = result.unwrap();

    this.model = {
      id: output.race.id,
      track: output.race.track,
      strengthOfField: output.strengthOfField,
    } as RaceWithSOFDTO;
  }

  getResponseModel(): GetRaceWithSOFResponseModel | null {
    return this.model;
  }

  get responseModel(): GetRaceWithSOFResponseModel {
    if (!this.model) {
      throw new Error('Presenter not presented');
    }

    return this.model;
  }

  get viewModel(): GetRaceWithSOFResponseModel {
    return this.responseModel;
  }
}
