import 'dotenv/config';
import fs from 'fs';
import os from 'os';
import path from 'path';
import {
  buildForecastFeedAuditReport,
  filterRainmakerFeedByEtDate,
  type RainmakerPublicEventsFeed,
  renderForecastFeedAuditMarkdown,
} from '../services/forecast-feed-audit';
import { getCurrentEtDateKey } from '../lib/league-windows';
import {
  fetchCurrentOdds,
  getTheOddsSportKey,
  hasTheOddsApiConfigured,
  type TheOddsCurrentEvent,
} from '../services/the-odds';

const args = process.argv.slice(2);

function getArgValue(flag: string): string | null {
  const index = args.indexOf(flag);
  if (index === -1) return null;
  return args[index + 1] || null;
}

function hasFlag(flag: string): boolean {
  return args.includes(flag);
}

function normalizeApiUrl(input: string | null): string {
  const fallbackBase = process.env.FRONTEND_URL || 'http://127.0.0.1:3021';
  const raw = (input || `${fallbackBase.replace(/\/$/, '')}/api/events`).trim();
  if (raw.endsWith('/api/events')) return raw;
  return `${raw.replace(/\/$/, '')}/api/events`;
}

function buildTimestampSlug(date: Date): string {
  return date.toISOString().replace(/[:.]/g, '-');
}

function buildOutputPaths(outputDir: string, auditedAt: Date): { jsonPath: string; markdownPath: string } {
  const slug = buildTimestampSlug(auditedAt);
  return {
    jsonPath: path.join(outputDir, `forecast-feed-audit-${slug}.json`),
    markdownPath: path.join(outputDir, `forecast-feed-audit-${slug}.md`),
  };
}

async function fetchRainmakerFeed(apiUrl: string): Promise<RainmakerPublicEventsFeed> {
  const response = await fetch(apiUrl, { signal: AbortSignal.timeout(30_000) });
  if (!response.ok) {
    const body = await response.text().catch(() => '');
    throw new Error(`Rainmaker feed ${response.status}: ${body || response.statusText}`);
  }
  return await response.json() as RainmakerPublicEventsFeed;
}

async function fetchThirdPartyByLeague(feed: RainmakerPublicEventsFeed): Promise<Record<string, TheOddsCurrentEvent[]>> {
  const output: Record<string, TheOddsCurrentEvent[]> = {};
  const leagues = [...new Set(Object.keys(feed.events || {}).filter(Boolean))];

  for (const league of leagues) {
    const sportKey = getTheOddsSportKey(league);
    if (!sportKey) {
      output[league] = [];
      continue;
    }

    output[league] = await fetchCurrentOdds({
      sportKey,
      markets: ['h2h', 'spreads', 'totals'],
    });
  }

  return output;
}

async function main() {
  if (!hasTheOddsApiConfigured()) {
    throw new Error('THE_ODDS_API_KEY is not configured');
  }

  const auditedAt = new Date();
  const apiUrl = normalizeApiUrl(getArgValue('--api-url'));
  const outputDir = getArgValue('--output-dir') || path.join(os.tmpdir(), 'rainmaker-forecast-audits');
  const failOnFindings = !hasFlag('--no-fail-on-findings');
  const auditAllEvents = hasFlag('--all-events');
  const dateEt = getArgValue('--date') || getCurrentEtDateKey(auditedAt);

  const feed = await fetchRainmakerFeed(apiUrl);
  const scopedFeed = auditAllEvents ? feed : filterRainmakerFeedByEtDate(feed, dateEt);
  const thirdPartyByLeague = await fetchThirdPartyByLeague(scopedFeed);
  const report = buildForecastFeedAuditReport({
    feed: scopedFeed,
    thirdPartyByLeague,
    auditedAt: auditedAt.toISOString(),
  });

  fs.mkdirSync(outputDir, { recursive: true });
  const { jsonPath, markdownPath } = buildOutputPaths(outputDir, auditedAt);
  fs.writeFileSync(jsonPath, JSON.stringify(report, null, 2));
  fs.writeFileSync(markdownPath, renderForecastFeedAuditMarkdown(report));

  const issueSamples = report.events
    .filter((event) => event.issues.length > 0)
    .slice(0, 10)
    .map((event) => ({
      matchup: event.matchup,
      league: event.league,
      issues: event.issues,
      startDeltaMin: event.startDeltaMin,
      confidence: event.confidence,
    }));

  console.log(JSON.stringify({
    auditedAt: report.auditedAt,
    apiUrl,
    scope: auditAllEvents ? 'all-events' : `date_et:${dateEt}`,
    passed: report.passed,
    summary: report.summary,
    issueCounts: report.issueCounts,
    startDeltaDistribution: report.startDeltaDistribution,
    files: {
      json: jsonPath,
      markdown: markdownPath,
    },
    issueSamples,
  }, null, 2));

  if (failOnFindings && !report.passed) {
    process.exitCode = 1;
  }
}

if (require.main === module) {
  main().catch((err) => {
    console.error('[forecast-feed-audit] Fatal:', err);
    process.exit(1);
  });
}
