import { describe, it, expect, beforeEach, vi } from 'vitest';
import {
  GetSponsorshipPricingUseCase,
  GetSponsorshipPricingResult,
  GetSponsorshipPricingInput,
  GetSponsorshipPricingErrorCode,
} from './GetSponsorshipPricingUseCase';
import type { UseCaseOutputPort } from '@core/shared/application';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';

describe('GetSponsorshipPricingUseCase', () => {
  let useCase: GetSponsorshipPricingUseCase;
  let output: UseCaseOutputPort<GetSponsorshipPricingResult> & { present: ReturnType<typeof vi.fn> };

  beforeEach(() => {
    output = { present: vi.fn() } as unknown as UseCaseOutputPort<
      GetSponsorshipPricingResult
    > & { present: ReturnType<typeof vi.fn> };
    useCase = new GetSponsorshipPricingUseCase(output);
  });

  it('should present sponsorship pricing tiers', async () => {
    const input: GetSponsorshipPricingInput = {};

    const result = await useCase.execute(input);

    expect(result.isOk()).toBe(true);
    expect(result.unwrap()).toBeUndefined();
    expect(output.present).toHaveBeenCalledTimes(1);
    expect(output.present).toHaveBeenCalledWith({
      entityType: 'season',
      entityId: '',
      pricing: [
        { id: 'tier-bronze', level: 'Bronze', price: 100, currency: 'USD' },
        { id: 'tier-silver', level: 'Silver', price: 250, currency: 'USD' },
        { id: 'tier-gold', level: 'Gold', price: 500, currency: 'USD' },
      ],
    });
  });

  it('should return repository error when execution fails', async () => {
    const error = new Error('Something went wrong');
    const failingUseCase = new GetSponsorshipPricingUseCase({
      present: () => {
        throw error;
      },
    } as unknown as UseCaseOutputPort<GetSponsorshipPricingResult>);

    const input: GetSponsorshipPricingInput = {};

    const result = await failingUseCase.execute(input);

    expect(result.isErr()).toBe(true);
    const err = result.unwrapErr() as ApplicationErrorCode<
      GetSponsorshipPricingErrorCode,
      { message: string }
    >;
    expect(err.code).toBe('REPOSITORY_ERROR');
    expect(err.details.message).toBe('Something went wrong');
  });
});