/**
 * Application Use Case: GetPendingSponsorshipRequestsUseCase
 *
 * Retrieves pending sponsorship requests for an entity owner to review.
 */

import type { ISponsorshipRequestRepository } from '../../domain/repositories/ISponsorshipRequestRepository';
import type { ISponsorRepository } from '../../domain/repositories/ISponsorRepository';
import type { SponsorableEntityType } from '../../domain/entities/SponsorshipRequest';
import type { SponsorshipTier } from '../../domain/entities/SeasonSponsorship';
import type { PendingSponsorshipRequestsViewModel } from '../presenters/IPendingSponsorshipRequestsPresenter';
import { Result } from '@core/shared/application/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';

export interface GetPendingSponsorshipRequestsDTO {
  entityType: SponsorableEntityType;
  entityId: string;
}

export interface PendingSponsorshipRequestDTO {
  id: string;
  sponsorId: string;
  sponsorName: string;
  sponsorLogo?: string;
  tier: SponsorshipTier;
  offeredAmount: number;
  currency: string;
  formattedAmount: string;
  message?: string;
  createdAt: Date;
  platformFee: number;
  netAmount: number;
}

export interface GetPendingSponsorshipRequestsResultDTO {
  entityType: SponsorableEntityType;
  entityId: string;
  requests: PendingSponsorshipRequestDTO[];
  totalCount: number;
}

export class GetPendingSponsorshipRequestsUseCase {
  constructor(
    private readonly sponsorshipRequestRepo: ISponsorshipRequestRepository,
    private readonly sponsorRepo: ISponsorRepository,
  ) {}

  async execute(
    dto: GetPendingSponsorshipRequestsDTO,
  ): Promise<Result<PendingSponsorshipRequestsViewModel, ApplicationErrorCode<'REPOSITORY_ERROR'>>> {
    try {
      const requests = await this.sponsorshipRequestRepo.findPendingByEntity(
        dto.entityType,
        dto.entityId
      );

      const requestDTOs: PendingSponsorshipRequestDTO[] = [];

      for (const request of requests) {
        const sponsor = await this.sponsorRepo.findById(request.sponsorId);

        requestDTOs.push({
          id: request.id,
          sponsorId: request.sponsorId,
          sponsorName: sponsor?.name ?? 'Unknown Sponsor',
          ...(sponsor?.logoUrl !== undefined ? { sponsorLogo: sponsor.logoUrl } : {}),
          tier: request.tier,
          offeredAmount: request.offeredAmount.amount,
          currency: request.offeredAmount.currency,
          formattedAmount: request.offeredAmount.format(),
          ...(request.message !== undefined ? { message: request.message } : {}),
          createdAt: request.createdAt,
          platformFee: request.getPlatformFee().amount,
          netAmount: request.getNetAmount().amount,
        });
      }

      // Sort by creation date (newest first)
      requestDTOs.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());

      const viewModel: PendingSponsorshipRequestsViewModel = {
        entityType: dto.entityType,
        entityId: dto.entityId,
        requests: requestDTOs,
        totalCount: requestDTOs.length,
      };
      return Result.ok(viewModel);
    } catch {
      return Result.err({ code: 'REPOSITORY_ERROR', message: 'Failed to fetch pending sponsorship requests' });
    }
  }
}