import type { Result } from './Result';
import type { ApplicationErrorCode } from '../errors/ApplicationErrorCode';

/**
 * Async Use Case interface for queries.
 *
 * Queries do not change system state and return data directly.
 * The output must be a Result<T, ApplicationErrorCode<E>> where T is the data and E is an application error code,
 * to handle business rejections explicitly. Use cases do not throw errors; they use error codes in Result.
 *
 * Example:
 * ```typescript
 * export type YourUseCaseErrorCode =
 *   | 'SPONSOR_NOT_FOUND'
 *   | 'PRICING_NOT_CONFIGURED'
 *   | 'APPLICATIONS_CLOSED'
 *   | 'NO_SLOTS_AVAILABLE'
 *   | 'DUPLICATE_PENDING_REQUEST'
 *   | 'OFFER_BELOW_MINIMUM';
 *
 * export class ApplyForSponsorshipUseCase implements AsyncUseCase<Input, SuccessDTO, YourUseCaseErrorCode> {
 *   async execute(input: Input): Promise<Result<SuccessDTO, ApplicationErrorCode<YourUseCaseErrorCode>>> {
 *     // implementation
 *   }
 * }
 * ```
 *
 * @template Input - The input type for the use case
 * @template Success - The success type returned in the Result
 * @template ErrorCode - The error code type for ApplicationErrorCode
 */
export interface AsyncUseCase<Input, Success, ErrorCode extends string> {
  execute(input: Input): Promise<Result<Success, ApplicationErrorCode<ErrorCode>>>;
}