import { PrismaClient } from '@prisma/client';
import * as dotenv from 'dotenv';

dotenv.config();

(BigInt.prototype as any).toJSON = function () {
  return this.toString();
};

const prisma = new PrismaClient();

async function analyzeReversalMatches() {
  console.log('🔍 ANALYZING HT/FT REVERSAL MATCHES (1/2 & 2/1)');
  console.log('='.repeat(80));

  // Fetch all completed matches with HT and FT scores
  const matches = await prisma.match.findMany({
    where: {
      status: 'FT',
      htScoreHome: { not: null },
      htScoreAway: { not: null },
      scoreHome: { not: null },
      scoreAway: { not: null },
      oddCategories: { some: {} }
    },
    include: {
      homeTeam: true,
      awayTeam: true,
      league: true,
      oddCategories: { include: { selections: true } }
    },
    orderBy: { mstUtc: 'desc' }
  });

  console.log(`📊 Total completed matches with odds: ${matches.length}`);

  // Analyze HT/FT results
  const reversalMatches: any[] = [];
  let totalMatches = 0;
  let htftCounts: Record<string, number> = {
    '1/1': 0, '1/X': 0, '1/2': 0,
    'X/1': 0, 'X/X': 0, 'X/2': 0,
    '2/1': 0, '2/X': 0, '2/2': 0
  };

  for (const match of matches) {
    const htHome = match.htScoreHome!;
    const htAway = match.htScoreAway!;
    const ftHome = match.scoreHome!;
    const ftAway = match.scoreAway!;

    const htResult = htHome > htAway ? '1' : htHome === htAway ? 'X' : '2';
    const ftResult = ftHome > ftAway ? '1' : ftHome === ftAway ? 'X' : '2';
    const htft = `${htResult}/${ftResult}`;

    htftCounts[htft] = (htftCounts[htft] || 0) + 1;
    totalMatches++;

    if (htft === '1/2' || htft === '2/1') {
      // Extract odds
      let msHomeOdds: number | null = null;
      let msDrawOdds: number | null = null;
      let msAwayOdds: number | null = null;
      let htHomeOdds: number | null = null;
      let htDrawOdds: number | null = null;
      let htAwayOdds: number | null = null;

      for (const cat of match.oddCategories) {
        const catName = (cat.name || '').toLowerCase();
        const isHT = catName.includes('1.yarı');

        for (const sel of cat.selections) {
          const selName = (sel.name || '').toLowerCase();
          if (!sel.oddValue) continue;
          const odd = parseFloat(sel.oddValue.toString());

          if (catName.includes('maç sonucu') || catName.includes('1.yarı sonucu')) {
            if (selName === '1') { if (isHT) htHomeOdds = odd; else msHomeOdds = odd; }
            else if (selName === 'x' || selName === '0') { if (isHT) htDrawOdds = odd; else msDrawOdds = odd; }
            else if (selName === '2') { if (isHT) htAwayOdds = odd; else msAwayOdds = odd; }
          }
        }
      }

      if (!match.homeTeam || !match.awayTeam || !match.league) continue;

      reversalMatches.push({
        id: match.id,
        homeTeam: match.homeTeam.name,
        awayTeam: match.awayTeam.name,
        league: match.league.name,
        htHome, htAway, ftHome, ftAway,
        htft,
        msHomeOdds, msDrawOdds, msAwayOdds,
        htHomeOdds, htDrawOdds, htAwayOdds,
        date: match.mstUtc,
      });
    }
  }

  // Print HT/FT distribution
  console.log('\n📊 HT/FT DISTRIBUTION:');
  for (const [key, count] of Object.entries(htftCounts)) {
    const pct = (count / totalMatches * 100).toFixed(2);
    const marker = (key === '1/2' || key === '2/1') ? ' ⚠️ REVERSAL' : '';
    console.log(`   ${key}: ${count} (${pct}%)${marker}`);
  }

  console.log(`\n⚠️  TOTAL REVERSAL MATCHES: ${reversalMatches.length} (${(reversalMatches.length / totalMatches * 100).toFixed(2)}%)`);

  // ANALYSIS 1: League distribution
  console.log('\n📈 ANALYSIS 1: LEAGUE DISTRIBUTION OF REVERSALS');
  console.log('-'.repeat(80));
  const leagueCounts: Record<string, { total: number, reversal: number }> = {};

  for (const match of matches) {
    if (!match.league) continue;
    const htHome = match.htScoreHome!;
    const htAway = match.htScoreAway!;
    const ftHome = match.scoreHome!;
    const ftAway = match.scoreAway!;

    const htResult = htHome > htAway ? '1' : htHome === htAway ? 'X' : '2';
    const ftResult = ftHome > ftAway ? '1' : ftHome === ftAway ? 'X' : '2';
    const htft = `${htResult}/${ftResult}`;

    const league = match.league.name;
    if (!leagueCounts[league]) leagueCounts[league] = { total: 0, reversal: 0 };
    leagueCounts[league].total++;
    if (htft === '1/2' || htft === '2/1') leagueCounts[league].reversal++;
  }

  const leagueSorted = Object.entries(leagueCounts)
    .filter(([_, v]) => v.reversal > 0 && v.total >= 50)
    .sort((a, b) => (b[1].reversal / b[1].total) - (a[1].reversal / a[1].total))
    .slice(0, 20);

  console.log('\nTop 20 leagues by reversal rate (min 50 matches):');
  for (const [league, data] of leagueSorted) {
    const rate = (data.reversal / data.total * 100).toFixed(2);
    console.log(`   ${league}: ${data.reversal}/${data.total} (${rate}%)`);
  }

  // ANALYSIS 2: Odds patterns
  console.log('\n📈 ANALYSIS 2: ODDS PATTERNS IN REVERSAL MATCHES');
  console.log('-'.repeat(80));

  const ms1_2 = reversalMatches.filter(m => m.htft === '1/2');
  const ms2_1 = reversalMatches.filter(m => m.htft === '2/1');

  console.log(`\n1/2 Reversals: ${ms1_2.length}`);
  console.log(`2/1 Reversals: ${ms2_1.length}`);

  // MS odds analysis for 1/2
  const ms1_2_withOdds = ms1_2.filter(m => m.msHomeOdds && m.msAwayOdds);
  if (ms1_2_withOdds.length > 0) {
    const avgHomeOdd = ms1_2_withOdds.reduce((sum, m) => sum + m.msHomeOdds!, 0) / ms1_2_withOdds.length;
    const avgAwayOdd = ms1_2_withOdds.reduce((sum, m) => sum + m.msAwayOdds!, 0) / ms1_2_withOdds.length;
    const avgDrawOdd = ms1_2_withOdds.filter(m => m.msDrawOdds).reduce((sum, m) => sum + m.msDrawOdds!, 0) / ms1_2_withOdds.filter(m => m.msDrawOdds).length || 0;

    console.log(`\n   1/2 Matches - Average MS Odds:`);
    console.log(`   Home Win: ${avgHomeOdd.toFixed(2)} (HT was WINNING!)`);
    console.log(`   Draw: ${avgDrawOdd.toFixed(2)}`);
    console.log(`   Away Win: ${avgAwayOdd.toFixed(2)} (but AWAY won FT!)`);

    // Favorite analysis
    let favoriteWon = 0;
    let underdogWon = 0;
    let noFavorite = 0;

    for (const m of ms1_2_withOdds) {
      if (m.msHomeOdds! < m.msAwayOdds!) {
        // Home was favorite, but away won = UNDERDOG
        underdogWon++;
      } else if (m.msAwayOdds! < m.msHomeOdds!) {
        // Away was favorite and won = FAVORITE
        favoriteWon++;
      } else {
        noFavorite++;
      }
    }

    console.log(`\n   1/2 - Who was favored vs who won:`);
    console.log(`   Favorite won (Away was fav): ${favoriteWon} (${(favoriteWon / ms1_2_withOdds.length * 100).toFixed(1)}%)`);
    console.log(`   Underdog won (Home was fav): ${underdogWon} (${(underdogWon / ms1_2_withOdds.length * 100).toFixed(1)}%) ⚠️`);
  }

  // MS odds analysis for 2/1
  const ms2_1_withOdds = ms2_1.filter(m => m.msHomeOdds && m.msAwayOdds);
  if (ms2_1_withOdds.length > 0) {
    const avgHomeOdd = ms2_1_withOdds.reduce((sum, m) => sum + m.msHomeOdds!, 0) / ms2_1_withOdds.length;
    const avgAwayOdd = ms2_1_withOdds.reduce((sum, m) => sum + m.msAwayOdds!, 0) / ms2_1_withOdds.length;
    const avgDrawOdd = ms2_1_withOdds.filter(m => m.msDrawOdds).reduce((sum, m) => sum + m.msDrawOdds!, 0) / ms2_1_withOdds.filter(m => m.msDrawOdds).length || 0;

    console.log(`\n   2/1 Matches - Average MS Odds:`);
    console.log(`   Home Win: ${avgHomeOdd.toFixed(2)} (HOME won FT!)`);
    console.log(`   Draw: ${avgDrawOdd.toFixed(2)}`);
    console.log(`   Away Win: ${avgAwayOdd.toFixed(2)} (Away was WINNING at HT!)`);

    let favoriteWon = 0;
    let underdogWon = 0;

    for (const m of ms2_1_withOdds) {
      if (m.msAwayOdds! < m.msHomeOdds!) {
        // Away was favorite at HT, but home won = UNDERDOG
        underdogWon++;
      } else if (m.msHomeOdds! < m.msAwayOdds!) {
        // Home was favorite and won = FAVORITE
        favoriteWon++;
      }
    }

    console.log(`\n   2/1 - Who was favored vs who won:`);
    console.log(`   Favorite won (Home was fav): ${favoriteWon} (${(favoriteWon / ms2_1_withOdds.length * 100).toFixed(1)}%)`);
    console.log(`   Underdog won (Away was fav): ${underdogWon} (${(underdogWon / ms2_1_withOdds.length * 100).toFixed(1)}%) ⚠️`);
  }

  // ANALYSIS 3: Suspicious patterns
  console.log('\n📈 ANALYSIS 3: SUSPICIOUS PATTERNS');
  console.log('-'.repeat(80));

  // Pattern 1: Heavy favorite loses after leading (1/2 with low home odds)
  const suspicious_1_2 = ms1_2_withOdds.filter(m => m.msHomeOdds! < 1.5);
  console.log(`\n⚠️  PATTERN 1: Heavy Home Favorite loses after HT lead (MS Home Odds < 1.5):`);
  console.log(`   Count: ${suspicious_1_2.length}`);
  if (suspicious_1_2.length > 0) {
    const avgOdd = suspicious_1_2.reduce((sum, m) => sum + m.msHomeOdds!, 0) / suspicious_1_2.length;
    console.log(`   Avg Home Odds: ${avgOdd.toFixed(2)}`);
    console.log(`   Sample matches:`);
    suspicious_1_2.slice(0, 5).forEach(m => {
      console.log(`     ${m.league}: ${m.homeTeam} (${m.msHomeOdds}) vs ${m.awayTeam} (${m.msAwayOdds}) => HT: ${m.htHome}-${m.htAway}, FT: ${m.ftHome}-${m.ftAway}`);
    });
  }

  // Pattern 2: Heavy away favorite loses after leading (2/1 with low away odds)
  const suspicious_2_1 = ms2_1_withOdds.filter(m => m.msAwayOdds! < 1.5);
  console.log(`\n⚠️  PATTERN 2: Heavy Away Favorite loses after HT lead (MS Away Odds < 1.5):`);
  console.log(`   Count: ${suspicious_2_1.length}`);
  if (suspicious_2_1.length > 0) {
    const avgOdd = suspicious_2_1.reduce((sum, m) => sum + m.msAwayOdds!, 0) / suspicious_2_1.length;
    console.log(`   Avg Away Odds: ${avgOdd.toFixed(2)}`);
    console.log(`   Sample matches:`);
    suspicious_2_1.slice(0, 5).forEach(m => {
      console.log(`     ${m.league}: ${m.homeTeam} (${m.msHomeOdds}) vs ${m.awayTeam} (${m.msAwayOdds}) => HT: ${m.htHome}-${m.htAway}, FT: ${m.ftHome}-${m.ftAway}`);
    });
  }

  // ANALYSIS 4: HT Odds vs MS Odds correlation
  console.log('\n📈 ANALYSIS 4: HT ODDS CORRELATION');
  console.log('-'.repeat(80));

  const withHTOdds = reversalMatches.filter(m => m.htHomeOdds && m.htAwayOdds);
  if (withHTOdds.length > 0) {
    console.log(`\n   Matches with HT odds: ${withHTOdds.length}`);

    let htCorrectlyPredicted = 0;
    for (const m of withHTOdds) {
      const htFav = m.htHomeOdds! < m.htAwayOdds! ? '1' : m.htAwayOdds! < m.htHomeOdds! ? '2' : 'X';
      const htActual = m.htHome > m.htAway ? '1' : m.htAway > m.htHome ? '2' : 'X';
      if (htFav === htActual) htCorrectlyPredicted++;
    }
    console.log(`   HT Favorite correctly led at HT: ${htCorrectlyPredicted}/${withHTOdds.length} (${(htCorrectlyPredicted / withHTOdds.length * 100).toFixed(1)}%)`);

    // How often did HT favorite lose FT?
    let htFavoriteLostFT = 0;
    for (const m of withHTOdds) {
      const htFav = m.htHomeOdds! < m.htAwayOdds! ? '1' : m.htAwayOdds! < m.htHomeOdds! ? '2' : 'X';
      const ftActual = m.ftHome > m.ftAway ? '1' : m.ftAway > m.ftHome ? '2' : 'X';
      if (htFav !== ftActual) htFavoriteLostFT++;
    }
    console.log(`   HT Favorite lost FT: ${htFavoriteLostFT}/${withHTOdds.length} (${(htFavoriteLostFT / withHTOdds.length * 100).toFixed(1)}%) ⚠️`);
  }

  // ANALYSIS 5: Score patterns
  console.log('\n📈 ANALYSIS 5: SCORE PATTERNS IN REVERSALS');
  console.log('-'.repeat(80));

  // HT score distribution for reversals
  const htScores: Record<string, number> = {};
  for (const m of reversalMatches) {
    const key = `${m.htHome}-${m.htAway}`;
    htScores[key] = (htScores[key] || 0) + 1;
  }

  console.log('\nMost common HT scores in reversal matches:');
  Object.entries(htScores)
    .sort((a, b) => b[1] - a[1])
    .slice(0, 10)
    .forEach(([score, count]) => {
      console.log(`   HT ${score}: ${count} matches`);
    });

  // FT score distribution
  const ftScores: Record<string, number> = {};
  for (const m of reversalMatches) {
    const key = `${m.ftHome}-${m.ftAway}`;
    ftScores[key] = (ftScores[key] || 0) + 1;
  }

  console.log('\nMost common FT scores in reversal matches:');
  Object.entries(ftScores)
    .sort((a, b) => b[1] - a[1])
    .slice(0, 10)
    .forEach(([score, count]) => {
      console.log(`   FT ${score}: ${count} matches`);
    });

  // ANALYSIS 6: Goal difference patterns
  console.log('\n📈 ANALYSIS 6: COMEBACK MAGNITUDE');
  console.log('-'.repeat(80));

  let comebackBy1 = 0;
  let comebackBy2 = 0;
  let comebackBy3Plus = 0;

  for (const m of reversalMatches) {
    const htDiff = Math.abs(m.htHome - m.htAway);
    const ftDiff = Math.abs(m.ftHome - m.ftAway);

    if (m.htft === '1/2') {
      // Home was leading, away won
      const margin = (m.ftAway - m.ftHome);
      if (margin === 1) comebackBy1++;
      else if (margin === 2) comebackBy2++;
      else comebackBy3Plus++;
    } else {
      // Away was leading, home won
      const margin = (m.ftHome - m.ftAway);
      if (margin === 1) comebackBy1++;
      else if (margin === 2) comebackBy2++;
      else comebackBy3Plus++;
    }
  }

  console.log(`\n   Comeback by 1 goal: ${comebackBy1} (${(comebackBy1 / reversalMatches.length * 100).toFixed(1)}%)`);
  console.log(`   Comeback by 2 goals: ${comebackBy2} (${(comebackBy2 / reversalMatches.length * 100).toFixed(1)}%)`);
  console.log(`   Comeback by 3+ goals: ${comebackBy3Plus} (${(comebackBy3Plus / reversalMatches.length * 100).toFixed(1)}%) ⚠️`);

  // Show extreme comebacks
  const extremeComebacks = reversalMatches
    .filter(m => {
      if (m.htft === '1/2') return (m.ftAway - m.ftHome) >= 2;
      return (m.ftHome - m.ftAway) >= 2;
    })
    .sort((a, b) => {
      const diffA = a.htft === '1/2' ? (a.ftAway - a.ftHome) : (a.ftHome - a.ftAway);
      const diffB = b.htft === '1/2' ? (b.ftAway - b.ftHome) : (b.ftHome - b.ftAway);
      return diffB - diffA;
    })
    .slice(0, 10);

  console.log('\nTop 10 most extreme comebacks:');
  extremeComebacks.forEach(m => {
    const diff = m.htft === '1/2' ? (m.ftAway - m.ftHome) : (m.ftHome - m.ftAway);
    console.log(`   ${m.league}: ${m.homeTeam} vs ${m.awayTeam} | HT: ${m.htHome}-${m.htAway} => FT: ${m.ftHome}-${m.ftAway} (Diff: ${diff})`);
  });

  console.log('\n' + '='.repeat(80));
  console.log('✅ ANALYSIS COMPLETE');
  console.log('='.repeat(80));

  await prisma.$disconnect();
}

analyzeReversalMatches().catch(console.error);
