/**
 * Application Use Case: GetEntitySponsorshipPricingUseCase
 *
 * Retrieves sponsorship pricing configuration for any entity.
 * Used by sponsors to see available slots and prices.
 */

import type { ISponsorshipPricingRepository } from '../../domain/repositories/ISponsorshipPricingRepository';
import type { Logger } from '@core/shared/application';
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
import { Result } from '@core/shared/application/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { SponsorableEntityType } from '../../domain/entities/SponsorshipRequest';

export type SponsorshipEntityType = SponsorableEntityType;

export type GetEntitySponsorshipPricingInput = {
  entityType: SponsorshipEntityType;
  entityId: string;
};

export type SponsorshipPricingTier = {
  name: string;
  price: {
    amount: number;
    currency: string;
  };
  benefits: string[];
};

export type GetEntitySponsorshipPricingResult = {
  entityType: SponsorshipEntityType;
  entityId: string;
  acceptingApplications: boolean;
  customRequirements?: string;
  tiers: SponsorshipPricingTier[];
};

export type GetEntitySponsorshipPricingErrorCode =
  | 'ENTITY_NOT_FOUND'
  | 'PRICING_NOT_CONFIGURED'
  | 'REPOSITORY_ERROR';

export class GetEntitySponsorshipPricingUseCase {
  constructor(
    private readonly sponsorshipPricingRepo: ISponsorshipPricingRepository,
    private readonly logger: Logger,
    private readonly output: UseCaseOutputPort<GetEntitySponsorshipPricingResult>,
  ) {}

  async execute(
    input: GetEntitySponsorshipPricingInput,
  ): Promise<
    Result<void, ApplicationErrorCode<GetEntitySponsorshipPricingErrorCode, { message: string }>>
  > {
    this.logger.debug(
      `Executing GetEntitySponsorshipPricingUseCase for entityType: ${input.entityType}, entityId: ${input.entityId}`,
    );

    try {
      const pricing = await this.sponsorshipPricingRepo.findByEntity(
        input.entityType,
        input.entityId,
      );

      if (!pricing) {
        this.logger.info(
          `No pricing configured for entityType: ${input.entityType}, entityId: ${input.entityId}`,
        );

        return Result.err({
          code: 'PRICING_NOT_CONFIGURED',
          details: {
            message: `No sponsorship pricing configured for entityType: ${input.entityType}, entityId: ${input.entityId}`,
          },
        });
      }

      const tiers: SponsorshipPricingTier[] = [];

      if (pricing.mainSlot) {
        tiers.push({
          name: 'main',
          price: pricing.mainSlot.price,
          benefits: pricing.mainSlot.benefits,
        });
      }

      if (pricing.secondarySlots) {
        tiers.push({
          name: 'secondary',
          price: pricing.secondarySlots.price,
          benefits: pricing.secondarySlots.benefits,
        });
      }

      const result: GetEntitySponsorshipPricingResult = {
        entityType: input.entityType,
        entityId: input.entityId,
        acceptingApplications: pricing.acceptingApplications,
        ...(pricing.customRequirements !== undefined
          ? { customRequirements: pricing.customRequirements }
          : {}),
        tiers,
      };

      this.logger.info(
        `Successfully retrieved sponsorship pricing for entityType: ${input.entityType}, entityId: ${input.entityId}`,
      );
      this.output.present(result);

      return Result.ok(undefined);
    } catch (error) {
      this.logger.error(
        'Error executing GetEntitySponsorshipPricingUseCase',
        error instanceof Error ? error : new Error(String(error)),
      );

      return Result.err({
        code: 'REPOSITORY_ERROR',
        details: {
          message:
            error instanceof Error
              ? error.message
              : 'Failed to load sponsorship pricing',
        },
      });
    }
  }
}