import { Injectable, Logger } from "@nestjs/common";
import { PrismaService } from "../../../database/prisma.service";

@Injectable()
export class AiFeatureStoreService {
  private readonly logger = new Logger(AiFeatureStoreService.name);

  constructor(private readonly prisma: PrismaService) {}

  /**
   * Bir maç için AI özelliklerini hesaplar ve 'match_ai_features' tablosuna yazar.
   * Bu metod Feeder yeni veri çektiğinde tetiklenmelidir.
   */
  async calculateAndSaveFeatures(matchId: string): Promise<void> {
    const match = await this.prisma.match.findUnique({
      where: { id: matchId },
      include: {
        homeTeam: {
          include: { homeMatches: { take: 5, orderBy: { mstUtc: "desc" } } },
        },
        awayTeam: {
          include: { awayMatches: { take: 5, orderBy: { mstUtc: "desc" } } },
        },
      },
    });

    if (!match || !match.homeTeam || !match.awayTeam) return;

    // 1. Form Score Calculation (0-100)
    // Son 5 maçtaki galibiyet, beraberlik ve atılan gollerin ağırlıklı ortalaması
    const homeForm = this.calculateFormScore(match.homeTeam.homeMatches);
    const awayForm = this.calculateFormScore(match.awayTeam.awayMatches);

    // 2. ELO — Read from team_elo_ratings table (populated by AI Engine compute_elo.py)
    const homeElo = match.homeTeamId
      ? await this.getTeamElo(match.homeTeamId)
      : 1500.0;
    const awayElo = match.awayTeamId
      ? await this.getTeamElo(match.awayTeamId)
      : 1500.0;

    // 3. Missing Player Impact (Sakat/Cezalı etkisi)
    // Feeder'dan gelen lineups verisindeki eksik as oyuncuları analiz etmeliyiz.
    // Şimdilik 0.0 (Etkisiz) olarak set ediyoruz, ilerde Lineup analizi buraya eklenecek.
    const missingImpact = 0.0;

    // 4. Save to Feature Store
    await this.prisma.footballAiFeature.upsert({
      where: { matchId },
      update: {
        homeElo,
        awayElo,
        homeFormScore: homeForm,
        awayFormScore: awayForm,
        missingPlayersImpact: missingImpact,
        updatedAt: new Date(),
      },
      create: {
        matchId,
        homeElo,
        awayElo,
        homeFormScore: homeForm,
        awayFormScore: awayForm,
        missingPlayersImpact: missingImpact,
      },
    });

    this.logger.debug(
      `Features calculated for match ${matchId} (Home Form: ${homeForm}, Away Form: ${awayForm})`,
    );
  }

  /**
   * Form Puanı Hesaplama Algoritması (V17 Simplified)
   * W=30, D=10, L=0 puan. + Gol başına 5 puan (max 15).
   * Toplam skor 0-100 arasına normalize edilir.
   */
  private calculateFormScore(matches: any[]): number {
    if (!matches || matches.length === 0) return 50; // Nötr form

    let totalPoints = 0;
    const maxPoints = matches.length * 45; // Max olası puan (30win + 15goal)

    for (const m of matches) {
      // Skor kontrolü (bazı maçlar oynanmamış olabilir)
      if (m.scoreHome === null || m.scoreAway === null) continue;

      const isWin = m.scoreHome > m.scoreAway; // Home team context
      const isDraw = m.scoreHome === m.scoreAway;

      if (isWin) totalPoints += 30;
      else if (isDraw) totalPoints += 10;

      const goals = Math.min(m.scoreHome, 3); // Max 3 gol katkısı
      totalPoints += goals * 5;
    }

    // Normalize to 0-100
    // Eğer hiç maç oynanmadıysa yine 50 dön.
    return matches.length > 0 ? (totalPoints / maxPoints) * 100 : 50;
  }

  /**
   * team_elo_ratings tablosundan takımın güncel ELO puanını okur.
   * Kayıt yoksa varsayılan 1500.0 döner.
   */
  private async getTeamElo(teamId: string): Promise<number> {
    const row = await this.prisma.teamEloRating.findUnique({
      where: { teamId },
      select: { overallElo: true },
    });
    return row?.overallElo ?? 1500.0;
  }
}
