/**
 * Application Use Case: GetSponsorUseCase
 *
 * Retrieves a single sponsor by ID.
 */

import type { ISponsorRepository } from '../../domain/repositories/ISponsorRepository';
import { Result } from '@core/shared/application/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { UseCaseOutputPort } from '@core/shared/application';
import type { Sponsor } from '../../domain/entities/sponsor/Sponsor';

export type GetSponsorInput = {
  sponsorId: string;
};

export type GetSponsorResult = {
  sponsor: Sponsor;
};

export type GetSponsorErrorCode = 'SPONSOR_NOT_FOUND' | 'REPOSITORY_ERROR';

export class GetSponsorUseCase {
  constructor(
    private readonly sponsorRepository: ISponsorRepository,
    private readonly output: UseCaseOutputPort<GetSponsorResult>,
  ) {}

  async execute(input: GetSponsorInput): Promise<Result<void, ApplicationErrorCode<GetSponsorErrorCode, { message: string }>>> {
    try {
      const sponsor = await this.sponsorRepository.findById(input.sponsorId);

      if (!sponsor) {
        return Result.err({
          code: 'SPONSOR_NOT_FOUND',
          details: {
            message: 'Sponsor not found',
          },
        });
      }

      const result: GetSponsorResult = {
        sponsor,
      };

      this.output.present(result);

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

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