import { Injectable, Logger } from "@nestjs/common";
import { PrismaService } from "../../database/prisma.service";
import { HttpService } from "@nestjs/axios";
import { firstValueFrom } from "rxjs";
import * as fs from "fs";
import * as path from "path";

@Injectable()
export class LeagueTiersService {
  private readonly logger = new Logger(LeagueTiersService.name);
  private readonly qualifiedLeaguesPath = path.join(
    process.cwd(),
    "qualified_leagues.json",
  );

  constructor(
    private readonly prisma: PrismaService,
    private readonly httpService: HttpService,
  ) {}

  // ─── READ ──────────────────────────────────────────────────

  async findAll() {
    return this.prisma.leagueTier.findMany({
      include: {
        league: {
          include: { country: true },
        },
      },
      orderBy: [{ tier: "asc" }, { createdAt: "asc" }],
    });
  }

  async findActive() {
    return this.prisma.leagueTier.findMany({
      where: { isActive: true },
      include: {
        league: {
          include: { country: true },
        },
      },
      orderBy: [{ tier: "asc" }, { createdAt: "asc" }],
    });
  }

  async findByTier(tier: number) {
    return this.prisma.leagueTier.findMany({
      where: { tier, isActive: true },
      include: {
        league: {
          include: { country: true },
        },
      },
      orderBy: { createdAt: "asc" },
    });
  }

  // ─── WRITE ─────────────────────────────────────────────────

  async addLeague(
    leagueId: string,
    tier: number = 2,
    notes?: string,
    addedBy?: string,
  ) {
    const result = await this.prisma.leagueTier.upsert({
      where: { leagueId },
      create: {
        leagueId,
        tier,
        isActive: true,
        notes,
        addedBy,
      },
      update: {
        tier,
        isActive: true,
        notes: notes || undefined,
        addedBy: addedBy || undefined,
      },
      include: {
        league: { include: { country: true } },
      },
    });

    // Auto-sync and retrain
    await this.syncQualifiedLeagues();
    this.triggerModelRetrain().catch((err) =>
      this.logger.error(`Retrain trigger failed: ${err.message}`),
    );

    return result;
  }

  async removeLeague(leagueId: string) {
    const result = await this.prisma.leagueTier.update({
      where: { leagueId },
      data: { isActive: false },
    });

    await this.syncQualifiedLeagues();

    return result;
  }

  async updateTier(leagueId: string, tier: number) {
    return this.prisma.leagueTier.update({
      where: { leagueId },
      data: { tier },
    });
  }

  async deleteLeague(leagueId: string) {
    const result = await this.prisma.leagueTier.delete({
      where: { leagueId },
    });

    await this.syncQualifiedLeagues();

    return result;
  }

  // ─── SYNC qualified_leagues.json ───────────────────────────

  async syncQualifiedLeagues(): Promise<{ count: number; path: string }> {
    const activeTiers = await this.prisma.leagueTier.findMany({
      where: { isActive: true },
      select: { leagueId: true },
    });

    const leagueIds = activeTiers.map((t) => t.leagueId);

    fs.writeFileSync(
      this.qualifiedLeaguesPath,
      JSON.stringify(leagueIds, null, 2),
      "utf-8",
    );

    this.logger.log(
      `Synced ${leagueIds.length} leagues to qualified_leagues.json`,
    );

    return { count: leagueIds.length, path: this.qualifiedLeaguesPath };
  }

  // ─── TRIGGER MODEL RETRAIN ─────────────────────────────────

  async triggerModelRetrain(): Promise<{ status: string; message: string }> {
    const aiEngineUrl = process.env.AI_ENGINE_URL || "http://localhost:8000";

    try {
      const response = await firstValueFrom(
        this.httpService.post(
          `${aiEngineUrl}/v1/admin/retrain`,
          { reason: "league_tier_change" },
          { timeout: 10000 },
        ),
      );

      this.logger.log(
        `Model retrain triggered: ${JSON.stringify(response.data)}`,
      );
      return {
        status: "triggered",
        message: "Model retraining started in background",
      };
    } catch (error: unknown) {
      const message =
        error instanceof Error ? error.message : String(error);
      this.logger.warn(
        `Could not trigger retrain (AI engine may not support it yet): ${message}`,
      );
      return {
        status: "skipped",
        message: `AI engine retrain endpoint not available: ${message}`,
      };
    }
  }

  // ─── STATS ─────────────────────────────────────────────────

  async getStats() {
    const tiers = await this.prisma.leagueTier.groupBy({
      by: ["tier"],
      where: { isActive: true },
      _count: true,
    });

    const totalActive = tiers.reduce((sum, t) => sum + t._count, 0);

    // Count matches in qualified leagues
    const activeLeagueIds = (
      await this.prisma.leagueTier.findMany({
        where: { isActive: true },
        select: { leagueId: true },
      })
    ).map((t) => t.leagueId);

    const matchCount = await this.prisma.match.count({
      where: {
        leagueId: { in: activeLeagueIds },
        sport: "football",
        status: "FT",
      },
    });

    return {
      tiers: tiers.map((t) => ({
        tier: t.tier,
        count: t._count,
      })),
      totalActiveLeagues: totalActive,
      totalQualifiedMatches: matchCount,
    };
  }
}
