/**
 * Application Use Case: GetSponsorSponsorshipsUseCase
 *
 * Returns detailed sponsorship information for a sponsor's campaigns/sponsorships page.
 */

import type { ISponsorRepository } from '../../domain/repositories/ISponsorRepository';
import type { ISeasonSponsorshipRepository } from '../../domain/repositories/ISeasonSponsorshipRepository';
import type { ISeasonRepository } from '../../domain/repositories/ISeasonRepository';
import type { ILeagueRepository } from '../../domain/repositories/ILeagueRepository';
import type { ILeagueMembershipRepository } from '../../domain/repositories/ILeagueMembershipRepository';
import type { IRaceRepository } from '../../domain/repositories/IRaceRepository';
import type { SponsorshipTier, SponsorshipStatus } from '../../domain/entities/SeasonSponsorship';
import type { SponsorSponsorshipsViewModel } from '../presenters/ISponsorSponsorshipsPresenter';
import { Result } from '@core/shared/application/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';

export interface GetSponsorSponsorshipsQueryParams {
  sponsorId: string;
}

export interface SponsorshipDetailDTO {
  id: string;
  leagueId: string;
  leagueName: string;
  seasonId: string;
  seasonName: string;
  seasonStartDate?: Date;
  seasonEndDate?: Date;
  tier: SponsorshipTier;
  status: SponsorshipStatus;
  pricing: {
    amount: number;
    currency: string;
  };
  platformFee: {
    amount: number;
    currency: string;
  };
  netAmount: {
    amount: number;
    currency: string;
  };
  metrics: {
    drivers: number;
    races: number;
    completedRaces: number;
    impressions: number;
  };
  createdAt: Date;
  activatedAt?: Date;
}

export interface SponsorSponsorshipsDTO {
  sponsorId: string;
  sponsorName: string;
  sponsorships: SponsorshipDetailDTO[];
  summary: {
    totalSponsorships: number;
    activeSponsorships: number;
    totalInvestment: number;
    totalPlatformFees: number;
    currency: string;
  };
}

export class GetSponsorSponsorshipsUseCase {
  constructor(
    private readonly sponsorRepository: ISponsorRepository,
    private readonly seasonSponsorshipRepository: ISeasonSponsorshipRepository,
    private readonly seasonRepository: ISeasonRepository,
    private readonly leagueRepository: ILeagueRepository,
    private readonly leagueMembershipRepository: ILeagueMembershipRepository,
    private readonly raceRepository: IRaceRepository,
  ) {}

  async execute(
    params: GetSponsorSponsorshipsQueryParams,
  ): Promise<Result<SponsorSponsorshipsViewModel, ApplicationErrorCode<'REPOSITORY_ERROR'>>> {
    try {
      const { sponsorId } = params;

      const sponsor = await this.sponsorRepository.findById(sponsorId);
      if (!sponsor) {
        return Result.ok(null);
      }

      // Get all sponsorships for this sponsor
      const sponsorships = await this.seasonSponsorshipRepository.findBySponsorId(sponsorId);

      const sponsorshipDetails: SponsorshipDetailDTO[] = [];
      let totalInvestment = 0;
      let totalPlatformFees = 0;

      for (const sponsorship of sponsorships) {
        // Get season to find league
        const season = await this.seasonRepository.findById(sponsorship.seasonId);
        if (!season) continue;

        const league = await this.leagueRepository.findById(season.leagueId);
        if (!league) continue;

        // Get membership count for this league
        const memberships = await this.leagueMembershipRepository.getLeagueMembers(season.leagueId);
        const driverCount = memberships.length;

        // Get races for this league
        const races = await this.raceRepository.findByLeagueId(season.leagueId);
        const completedRaces = races.filter(r => r.status === 'completed').length;

        // Calculate impressions
        const impressions = completedRaces * driverCount * 100;

        // Calculate platform fee (10%)
        const platformFee = sponsorship.getPlatformFee();
        const netAmount = sponsorship.getNetAmount();

        totalInvestment += sponsorship.pricing.amount;
        totalPlatformFees += platformFee.amount;

        sponsorshipDetails.push({
          id: sponsorship.id,
          leagueId: league.id,
          leagueName: league.name,
          seasonId: season.id,
          seasonName: season.name,
          ...(season.startDate !== undefined ? { seasonStartDate: season.startDate } : {}),
          ...(season.endDate !== undefined ? { seasonEndDate: season.endDate } : {}),
          tier: sponsorship.tier,
          status: sponsorship.status,
          pricing: {
            amount: sponsorship.pricing.amount,
            currency: sponsorship.pricing.currency,
          },
          platformFee: {
            amount: platformFee.amount,
            currency: platformFee.currency,
          },
          netAmount: {
            amount: netAmount.amount,
            currency: netAmount.currency,
          },
          metrics: {
            drivers: driverCount,
            races: races.length,
            completedRaces,
            impressions,
          },
          createdAt: sponsorship.createdAt,
          ...(sponsorship.activatedAt !== undefined ? { activatedAt: sponsorship.activatedAt } : {}),
        });
      }

      const activeSponsorships = sponsorships.filter(s => s.status === 'active').length;

      const dto: SponsorSponsorshipsDTO = {
        sponsorId,
        sponsorName: sponsor.name,
        sponsorships: sponsorshipDetails,
        summary: {
          totalSponsorships: sponsorships.length,
          activeSponsorships,
          totalInvestment,
          totalPlatformFees,
          currency: 'USD',
        },
      };

      return Result.ok(dto);
    } catch {
      return Result.err({ code: 'REPOSITORY_ERROR', message: 'Failed to fetch sponsor sponsorships' });
    }
  }
}