#!/usr/bin/env npx tsx
/**
 * Comprehensive 40-question audit of the sports data system
 * Tests all 4 leagues with various query types to identify issues
 */
require('dotenv').config({ path: '.env.local' });
require('dotenv').config({ path: '.env' });

import { getSportsDataForQuery } from '../lib/chat';
import { getSportsDb, isSportsDbEnabled } from '../lib/sportsDb';

interface AuditResult {
  id: number;
  category: string;
  question: string;
  status: 'PASS' | 'FAIL' | 'PARTIAL' | 'NO_DATA';
  responseLength: number;
  hasData: boolean;
  issues: string[];
  preview: string;
  executionTime: number;
}

const AUDIT_QUESTIONS = [
  // NHL Questions (1-10)
  { id: 1, category: 'NHL', question: 'What NHL games are on today?' },
  { id: 2, category: 'NHL', question: 'NHL standings' },
  { id: 3, category: 'NHL', question: 'Toronto Maple Leafs upcoming games' },
  { id: 4, category: 'NHL', question: 'Who is playing in the NHL this week?' },
  { id: 5, category: 'NHL', question: 'NHL teams list' },
  { id: 6, category: 'NHL', question: 'Vegas Golden Knights schedule' },
  { id: 7, category: 'NHL', question: 'Recent NHL scores' },
  { id: 8, category: 'NHL', question: 'Edmonton Oilers vs Calgary Flames' },
  { id: 9, category: 'NHL', question: 'NHL playoff picture' },
  { id: 10, category: 'NHL', question: 'Best NHL teams this season' },

  // NBA Questions (11-20)
  { id: 11, category: 'NBA', question: 'NBA games tonight' },
  { id: 12, category: 'NBA', question: 'NBA standings 2025-26' },
  { id: 13, category: 'NBA', question: 'Los Angeles Lakers schedule' },
  { id: 14, category: 'NBA', question: 'Boston Celtics upcoming games' },
  { id: 15, category: 'NBA', question: 'NBA Eastern Conference standings' },
  { id: 16, category: 'NBA', question: 'NBA Western Conference standings' },
  { id: 17, category: 'NBA', question: 'Recent NBA scores' },
  { id: 18, category: 'NBA', question: 'Warriors vs Lakers' },
  { id: 19, category: 'NBA', question: 'NBA games this weekend' },
  { id: 20, category: 'NBA', question: 'Top NBA teams' },

  // NFL Questions (21-28)
  { id: 21, category: 'NFL', question: 'NFL games this week' },
  { id: 22, category: 'NFL', question: 'NFL standings' },
  { id: 23, category: 'NFL', question: 'Kansas City Chiefs schedule' },
  { id: 24, category: 'NFL', question: 'NFL playoff teams' },
  { id: 25, category: 'NFL', question: 'Recent NFL scores' },
  { id: 26, category: 'NFL', question: 'Dallas Cowboys upcoming games' },
  { id: 27, category: 'NFL', question: 'Super Bowl teams' },
  { id: 28, category: 'NFL', question: 'Best NFL teams this season' },

  // MLB Questions (29-36)
  { id: 29, category: 'MLB', question: 'MLB games today' },
  { id: 30, category: 'MLB', question: 'MLB standings' },
  { id: 31, category: 'MLB', question: 'New York Yankees schedule' },
  { id: 32, category: 'MLB', question: 'Los Angeles Dodgers upcoming games' },
  { id: 33, category: 'MLB', question: 'When does MLB season start?' },
  { id: 34, category: 'MLB', question: 'MLB spring training' },
  { id: 35, category: 'MLB', question: 'World Series teams' },
  { id: 36, category: 'MLB', question: 'Best MLB teams' },

  // Cross-sport and Edge Cases (37-40)
  { id: 37, category: 'GENERAL', question: 'What sports games are on today?' },
  { id: 38, category: 'GENERAL', question: 'Sports schedule this week' },
  { id: 39, category: 'EDGE', question: 'Games on February 15, 2026' },
  { id: 40, category: 'EDGE', question: 'Which team should I bet on?' },
];

function analyzeResponse(question: string, result: any): { issues: string[]; status: 'PASS' | 'FAIL' | 'PARTIAL' | 'NO_DATA' } {
  const issues: string[] = [];
  const context = result?.context || '';
  const contextLower = context.toLowerCase();
  const questionLower = question.toLowerCase();

  // Check if we got any response
  if (!context || context.length < 20) {
    return { issues: ['No meaningful data returned'], status: 'NO_DATA' };
  }

  // Check for error messages
  if (contextLower.includes('error') || contextLower.includes('failed') || contextLower.includes('unavailable')) {
    issues.push('Response contains error indicators');
  }

  // Check for outdated data (years before 2025)
  // FIX: Use negative lookahead to not match "2025-26" season format
  const oldYearMatch = context.match(/\b(19\d{2}|200\d|201\d|202[0-4])(?!-\d{2})\b/g);
  if (oldYearMatch) {
    const currentYear = new Date().getFullYear();
    const oldYears = oldYearMatch.filter(y => parseInt(y) < currentYear - 1);
    if (oldYears.length > 0) {
      issues.push(`Contains potentially outdated years: ${[...new Set(oldYears)].join(', ')}`);
    }
  }

  // Sport-specific checks
  if (questionLower.includes('nhl')) {
    if (!contextLower.includes('nhl') && !contextLower.includes('hockey')) {
      issues.push('NHL query but response missing NHL context');
    }
  }
  if (questionLower.includes('nba')) {
    if (!contextLower.includes('nba') && !contextLower.includes('basketball')) {
      issues.push('NBA query but response missing NBA context');
    }
  }
  if (questionLower.includes('nfl')) {
    if (!contextLower.includes('nfl') && !contextLower.includes('football')) {
      issues.push('NFL query but response missing NFL context');
    }
  }
  if (questionLower.includes('mlb')) {
    if (!contextLower.includes('mlb') && !contextLower.includes('baseball') && !contextLower.includes('off-season')) {
      issues.push('MLB query but response missing MLB context');
    }
  }

  // Check for games/schedule queries
  if (questionLower.includes('game') || questionLower.includes('schedule')) {
    if (!contextLower.includes('game') && !contextLower.includes('@') && !contextLower.includes('vs')) {
      issues.push('Games query but no game matchups in response');
    }
  }

  // Check for standings queries
  if (questionLower.includes('standing')) {
    if (!contextLower.includes('standing') && !contextLower.match(/\d+-\d+/)) {
      issues.push('Standings query but no standings data in response');
    }
  }

  // Check for team-specific queries
  const teamNames = ['lakers', 'celtics', 'warriors', 'maple leafs', 'golden knights', 'oilers', 'flames',
                      'chiefs', 'cowboys', 'yankees', 'dodgers', 'hawks', 'bulls', 'heat'];
  for (const team of teamNames) {
    if (questionLower.includes(team) && !contextLower.includes(team.split(' ')[0])) {
      // Check if at least part of team name is in response
      const teamParts = team.split(' ');
      const hasAnyPart = teamParts.some(part => contextLower.includes(part));
      if (!hasAnyPart) {
        issues.push(`Team "${team}" mentioned in query but not found in response`);
      }
    }
  }

  // Determine status
  if (issues.length === 0) {
    return { issues, status: 'PASS' };
  } else if (issues.length <= 2 && context.length > 100) {
    return { issues, status: 'PARTIAL' };
  } else {
    return { issues, status: 'FAIL' };
  }
}

async function runAudit() {
  console.log('=' .repeat(80));
  console.log('SPORTS DATA SYSTEM AUDIT - 40 Question Comprehensive Test');
  console.log('=' .repeat(80));
  console.log(`Started: ${new Date().toISOString()}`);
  console.log();

  // First, check database stats
  if (isSportsDbEnabled()) {
    const db = getSportsDb();
    console.log('DATABASE STATISTICS:');
    console.log('-'.repeat(40));

    for (const league of ['nba', 'nfl', 'nhl', 'mlb']) {
      const count = await db.sportsGame.count({ where: { league } });
      const latest = await db.sportsGame.findFirst({
        where: { league },
        orderBy: { gameDate: 'desc' },
        select: { gameDate: true }
      });
      const earliest = await db.sportsGame.findFirst({
        where: { league },
        orderBy: { gameDate: 'asc' },
        select: { gameDate: true }
      });

      const latestDate = latest?.gameDate?.toISOString().split('T')[0] || 'N/A';
      const earliestDate = earliest?.gameDate?.toISOString().split('T')[0] || 'N/A';
      console.log(`${league.toUpperCase()}: ${count} games (${earliestDate} to ${latestDate})`);
    }
    console.log();
  }

  const results: AuditResult[] = [];
  const delayMs = 2000; // 2 second delay between queries to avoid rate limits

  for (const q of AUDIT_QUESTIONS) {
    console.log(`[${q.id}/40] Testing: ${q.question}`);

    const startTime = Date.now();
    try {
      const result = await getSportsDataForQuery(q.question);
      const executionTime = Date.now() - startTime;

      const context = result?.context || '';
      const analysis = analyzeResponse(q.question, result);

      const auditResult: AuditResult = {
        id: q.id,
        category: q.category,
        question: q.question,
        status: analysis.status,
        responseLength: context.length,
        hasData: context.length > 50,
        issues: analysis.issues,
        preview: context.substring(0, 150).replace(/\n/g, ' '),
        executionTime
      };

      results.push(auditResult);

      const statusIcon = {
        'PASS': '✅',
        'PARTIAL': '⚠️',
        'FAIL': '❌',
        'NO_DATA': '📭'
      }[analysis.status];

      console.log(`    ${statusIcon} ${analysis.status} (${context.length} chars, ${executionTime}ms)`);
      if (analysis.issues.length > 0) {
        analysis.issues.forEach(issue => console.log(`       - ${issue}`));
      }

    } catch (error) {
      const executionTime = Date.now() - startTime;
      results.push({
        id: q.id,
        category: q.category,
        question: q.question,
        status: 'FAIL',
        responseLength: 0,
        hasData: false,
        issues: [`Exception: ${error}`],
        preview: '',
        executionTime
      });
      console.log(`    ❌ EXCEPTION: ${error}`);
    }

    // Rate limit protection
    await new Promise(resolve => setTimeout(resolve, delayMs));
  }

  // Generate summary report
  console.log('\n' + '='.repeat(80));
  console.log('AUDIT SUMMARY REPORT');
  console.log('='.repeat(80));

  const byStatus = {
    PASS: results.filter(r => r.status === 'PASS'),
    PARTIAL: results.filter(r => r.status === 'PARTIAL'),
    FAIL: results.filter(r => r.status === 'FAIL'),
    NO_DATA: results.filter(r => r.status === 'NO_DATA')
  };

  console.log(`\nOVERALL RESULTS:`);
  console.log(`  ✅ PASS:    ${byStatus.PASS.length}/40 (${(byStatus.PASS.length/40*100).toFixed(1)}%)`);
  console.log(`  ⚠️  PARTIAL: ${byStatus.PARTIAL.length}/40 (${(byStatus.PARTIAL.length/40*100).toFixed(1)}%)`);
  console.log(`  ❌ FAIL:    ${byStatus.FAIL.length}/40 (${(byStatus.FAIL.length/40*100).toFixed(1)}%)`);
  console.log(`  📭 NO_DATA: ${byStatus.NO_DATA.length}/40 (${(byStatus.NO_DATA.length/40*100).toFixed(1)}%)`);

  // By category
  console.log(`\nRESULTS BY CATEGORY:`);
  for (const category of ['NHL', 'NBA', 'NFL', 'MLB', 'GENERAL', 'EDGE']) {
    const catResults = results.filter(r => r.category === category);
    const passed = catResults.filter(r => r.status === 'PASS' || r.status === 'PARTIAL').length;
    console.log(`  ${category}: ${passed}/${catResults.length} passing`);
  }

  // Issues summary
  console.log(`\nCOMMON ISSUES FOUND:`);
  const allIssues: Record<string, number> = {};
  results.forEach(r => {
    r.issues.forEach(issue => {
      const key = issue.split(':')[0]; // Group similar issues
      allIssues[key] = (allIssues[key] || 0) + 1;
    });
  });

  Object.entries(allIssues)
    .sort((a, b) => b[1] - a[1])
    .slice(0, 10)
    .forEach(([issue, count]) => {
      console.log(`  - ${issue}: ${count} occurrences`);
    });

  // Failed queries detail
  if (byStatus.FAIL.length > 0 || byStatus.NO_DATA.length > 0) {
    console.log(`\nFAILED/NO_DATA QUERIES:`);
    [...byStatus.FAIL, ...byStatus.NO_DATA].forEach(r => {
      console.log(`  [${r.id}] ${r.question}`);
      r.issues.forEach(issue => console.log(`       - ${issue}`));
    });
  }

  // Data gaps
  console.log(`\nDATA GAPS IDENTIFIED:`);
  const noDataCategories = new Map<string, string[]>();
  byStatus.NO_DATA.forEach(r => {
    if (!noDataCategories.has(r.category)) {
      noDataCategories.set(r.category, []);
    }
    noDataCategories.get(r.category)!.push(r.question);
  });

  if (noDataCategories.size === 0) {
    console.log('  No significant data gaps found');
  } else {
    noDataCategories.forEach((questions, category) => {
      console.log(`  ${category}:`);
      questions.forEach(q => console.log(`    - ${q}`));
    });
  }

  // Performance stats
  const avgTime = results.reduce((sum, r) => sum + r.executionTime, 0) / results.length;
  const maxTime = Math.max(...results.map(r => r.executionTime));
  const minTime = Math.min(...results.map(r => r.executionTime));

  console.log(`\nPERFORMANCE STATISTICS:`);
  console.log(`  Average response time: ${avgTime.toFixed(0)}ms`);
  console.log(`  Fastest response: ${minTime}ms`);
  console.log(`  Slowest response: ${maxTime}ms`);

  // Save detailed results to JSON
  const reportPath = '/tmp/sports_audit_report.json';
  const fs = await import('fs');
  fs.writeFileSync(reportPath, JSON.stringify({
    timestamp: new Date().toISOString(),
    summary: {
      total: 40,
      pass: byStatus.PASS.length,
      partial: byStatus.PARTIAL.length,
      fail: byStatus.FAIL.length,
      noData: byStatus.NO_DATA.length,
      avgResponseTime: avgTime
    },
    results
  }, null, 2));

  console.log(`\nDetailed report saved to: ${reportPath}`);
  console.log(`\nAudit completed: ${new Date().toISOString()}`);

  return results;
}

runAudit().catch(console.error);
