import { Injectable, Logger } from "@nestjs/common";
import { PrismaService } from "../../database/prisma.service";
import {
  devig,
  overround,
  scoreDistribution,
  isCupLeague,
  OddsBlob,
} from "./devig.util";
import { ValueBoardMatch } from "./value-board.types";

// Turkish market keys as stored in live_matches.odds
const K = {
  MS: "Maç Sonucu",
  OU25: "2,5 Alt/Üst",
  BTTS: "Karşılıklı Gol",
  HT: "1. Yarı Sonucu",
  HT15: "1. Yarı 1,5 Alt/Üst",
  SCORE: "Maç Skoru",
} as const;

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

  constructor(private readonly prisma: PrismaService) {}

  /**
   * Upcoming matches with de-vigged (calibrated) probabilities for the main
   * markets, the market's correct-score distribution, half-time markets and a
   * derived expected-goals figure. Honest baseline — no fabricated value.
   */
  async getBoard(
    sport = "football",
    limit = 60,
  ): Promise<ValueBoardMatch[]> {
    const now = BigInt(Date.now());
    const rows = await this.prisma.liveMatch.findMany({
      where: {
        sport,
        status: "NS",
        mstUtc: { gt: now },
      },
      include: {
        league: { include: { country: true } },
        homeTeam: true,
        awayTeam: true,
      },
      orderBy: { mstUtc: "asc" },
      take: limit,
    });

    const board: ValueBoardMatch[] = [];
    for (const m of rows) {
      if (!m.odds || typeof m.odds !== "object" || Array.isArray(m.odds)) {
        continue;
      }
      const odds = m.odds as unknown as OddsBlob;

      const ms = devig(odds[K.MS], ["1", "X", "2"]);
      if (!ms) continue; // no real MS price → don't show (never fabricate)

      const ou = devig(odds[K.OU25], ["Alt", "Üst"]);
      const bt = devig(odds[K.BTTS], ["Var", "Yok"]);
      const ht = devig(odds[K.HT], ["1", "X", "2"]);
      const ht15 = devig(odds[K.HT15], ["Alt", "Üst"]);
      const score = scoreDistribution(odds[K.SCORE]);
      const vig = overround(odds[K.MS], ["1", "X", "2"]);

      const leanIdx = ms.indexOf(Math.max(...ms));
      const leanKey = (["1", "X", "2"] as const)[leanIdx];

      board.push({
        id: m.id,
        matchName:
          m.matchName || `${m.homeTeam?.name ?? "?"} vs ${m.awayTeam?.name ?? "?"}`,
        homeTeam: m.homeTeam?.name ?? "?",
        awayTeam: m.awayTeam?.name ?? "?",
        league: m.league?.name ?? "—",
        country: m.league?.country?.name ?? undefined,
        kickoff: Number(m.mstUtc ?? 0),
        isCup: isCupLeague(m.league?.name),
        vigPct: vig === null ? null : Math.round(vig * 1000) / 10,
        ms: { home: ms[0], draw: ms[1], away: ms[2] },
        ou25: ou ? { over: ou[1], under: ou[0] } : null,
        btts: bt ? { yes: bt[0], no: bt[1] } : null,
        htResult: ht ? { home: ht[0], draw: ht[1], away: ht[2] } : null,
        htOu15: ht15 ? { over: ht15[1], under: ht15[0] } : null,
        topScores: score.topScores,
        expectedGoals: score.expectedGoals,
        lean: { key: leanKey, prob: ms[leanIdx] },
      });
    }
    return board;
  }
}
