import { RatingEventRepository } from '../../domain/repositories/RatingEventRepository';
import { UserRatingRepository } from '../../domain/repositories/UserRatingRepository';
import { RatingSnapshotCalculator } from '../../domain/services/RatingSnapshotCalculator';
import { UserRatingDto } from '../dtos/UserRatingDto';

/**
 * Input for RecomputeUserRatingSnapshotUseCase
 */
export interface RecomputeUserRatingSnapshotInput {
  userId: string;
}

/**
 * Output for RecomputeUserRatingSnapshotUseCase
 */
export interface RecomputeUserRatingSnapshotOutput {
  snapshot: UserRatingDto;
}

/**
 * Use Case: RecomputeUserRatingSnapshotUseCase
 * 
 * Recomputes a user's rating snapshot from all events in the ledger.
 * Useful for:
 * - Algorithm updates
 * - Data corrections
 * - Manual recomputation
 */
export class RecomputeUserRatingSnapshotUseCase {
  constructor(
    private readonly ratingEventRepository: RatingEventRepository,
    private readonly userRatingRepository: UserRatingRepository,
  ) {}

  async execute(input: RecomputeUserRatingSnapshotInput): Promise<RecomputeUserRatingSnapshotOutput> {
    // 1. Load all events for the user
    const events = await this.ratingEventRepository.getAllByUserId(input.userId);

    // 2. Compute snapshot from events
    const snapshot = RatingSnapshotCalculator.calculate(input.userId, events);

    // 3. Save snapshot
    await this.userRatingRepository.save(snapshot);

    // 4. Convert to DTO for output
    const dto: UserRatingDto = {
      userId: snapshot.userId,
      driver: {
        value: snapshot.driver.value,
        confidence: snapshot.driver.confidence,
        sampleSize: snapshot.driver.sampleSize,
        trend: snapshot.driver.trend,
        lastUpdated: snapshot.driver.lastUpdated.toISOString(),
      },
      admin: {
        value: snapshot.admin.value,
        confidence: snapshot.admin.confidence,
        sampleSize: snapshot.admin.sampleSize,
        trend: snapshot.admin.trend,
        lastUpdated: snapshot.admin.lastUpdated.toISOString(),
      },
      steward: {
        value: snapshot.steward.value,
        confidence: snapshot.steward.confidence,
        sampleSize: snapshot.steward.sampleSize,
        trend: snapshot.steward.trend,
        lastUpdated: snapshot.steward.lastUpdated.toISOString(),
      },
      trust: {
        value: snapshot.trust.value,
        confidence: snapshot.trust.confidence,
        sampleSize: snapshot.trust.sampleSize,
        trend: snapshot.trust.trend,
        lastUpdated: snapshot.trust.lastUpdated.toISOString(),
      },
      fairness: {
        value: snapshot.fairness.value,
        confidence: snapshot.fairness.confidence,
        sampleSize: snapshot.fairness.sampleSize,
        trend: snapshot.fairness.trend,
        lastUpdated: snapshot.fairness.lastUpdated.toISOString(),
      },
      overallReputation: snapshot.overallReputation,
      createdAt: snapshot.createdAt.toISOString(),
      updatedAt: snapshot.updatedAt.toISOString(),
    };
    
    if (snapshot.calculatorVersion !== undefined) {
      dto.calculatorVersion = snapshot.calculatorVersion;
    }

    return { snapshot: dto };
  }
}