import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { HallOfFame } from './hall-of-fame.entity';
import { CommunityContribution } from '../community/community-contribution.entity';

@Injectable()
export class HallOfFameService {
  constructor(
    @InjectRepository(HallOfFame)
    private readonly hofRepo: Repository<HallOfFame>,
    @InjectRepository(CommunityContribution)
    private readonly contributionRepo: Repository<CommunityContribution>,
  ) {}

  async getCurrentRanking() {
    const period = this.getCurrentPeriod();
    return this.getRankingByPeriod(period);
  }

  async getRankingByPeriod(period: string) {
    // Check if already computed for this period
    const existing = await this.hofRepo.find({
      where: { period },
      order: { rank: 'ASC' },
      relations: ['character'],
    });
    if (existing.length) return existing;

    // Compute live from contributions (current month)
    if (period === this.getCurrentPeriod()) {
      return this.computeLiveRanking();
    }

    return [];
  }

  private async computeLiveRanking() {
    // Aggregate all contributions across all active goals for the current period
    const results = await this.contributionRepo
      .createQueryBuilder('cc')
      .select('cc.character_id', 'characterId')
      .addSelect('SUM(cc.contribution_value)', 'total')
      .groupBy('cc.character_id')
      .orderBy('total', 'DESC')
      .limit(10)
      .getRawMany();

    return results.map((r, i) => ({
      rank: i + 1,
      characterId: r.characterId,
      contributionTotal: Number(r.total),
      period: this.getCurrentPeriod(),
      badge: i === 0 ? `top1_${this.getCurrentPeriod()}` : null,
    }));
  }

  /**
   * Called at month end to freeze the Hall of Fame
   * Can be triggered via cron or manual API call
   */
  async freezePeriod(period: string) {
    const existing = await this.hofRepo.find({ where: { period } });
    if (existing.length) return existing; // Already frozen

    const results = await this.contributionRepo
      .createQueryBuilder('cc')
      .select('cc.character_id', 'characterId')
      .addSelect('SUM(cc.contribution_value)', 'total')
      .groupBy('cc.character_id')
      .orderBy('total', 'DESC')
      .limit(10)
      .getRawMany();

    const entries: HallOfFame[] = [];
    for (let i = 0; i < results.length; i++) {
      const r = results[i];
      const badge = `top${i + 1}_${period}`;
      const entry = this.hofRepo.create({
        characterId: r.characterId,
        period,
        rank: i + 1,
        contributionTotal: Number(r.total),
        badge,
      });
      entries.push(await this.hofRepo.save(entry));
    }

    return entries;
  }

  private getCurrentPeriod(): string {
    const now = new Date();
    const month = String(now.getMonth() + 1).padStart(2, '0');
    return `${now.getFullYear()}-${month}`;
  }
}
