import { ACTIVE_SEEDED_LEAGUES } from '../config/league-support';
import { ESPN_LEAGUES } from './espn-roster';
import {
  getPlayerPropMarketDefinitions,
  getRegisteredPlayerPropLeagues,
} from './player-prop-market-registry';
import { LEAGUE_MAP } from './sgo';
import { getTheOddsSportKey } from './the-odds';

export interface LeagueCoverageAuditEntry {
  league: string;
  seeded: boolean;
  sgoFeed: boolean;
  espnRoster: boolean;
  theOddsSport: boolean;
  registryStatCount: number;
  theOddsPropStatCount: number;
  endToEndReady: boolean;
  notes: string[];
}

export interface LeagueCoverageAuditReport {
  auditedAt: string;
  summary: {
    totalLeagues: number;
    registryLeagues: number;
    seededLeagues: number;
    endToEndReadyLeagues: number;
    rosterGapLeagues: number;
    partialTheOddsPropCoverageLeagues: number;
  };
  leagues: LeagueCoverageAuditEntry[];
}

function getCandidateLeagues(): string[] {
  return Array.from(new Set([
    ...Object.keys(LEAGUE_MAP),
    ...Object.keys(ESPN_LEAGUES),
    ...ACTIVE_SEEDED_LEAGUES,
    ...getRegisteredPlayerPropLeagues(),
  ])).sort((a, b) => a.localeCompare(b));
}

function buildLeagueCoverageEntry(league: string): LeagueCoverageAuditEntry {
  const definitions = getPlayerPropMarketDefinitions(league);
  const seeded = ACTIVE_SEEDED_LEAGUES.includes(league as (typeof ACTIVE_SEEDED_LEAGUES)[number]);
  const sgoFeed = Boolean(LEAGUE_MAP[league]);
  const espnRoster = Boolean(ESPN_LEAGUES[league]);
  const theOddsSport = Boolean(getTheOddsSportKey(league));
  const registryStatCount = definitions.length;
  const theOddsPropStatCount = definitions.filter((definition) => Boolean(definition.theOddsMarketKey)).length;
  const notes: string[] = [];

  if (registryStatCount > 0 && !seeded) notes.push('registry-supported but not seeded');
  if (seeded && !sgoFeed) notes.push('seeded without SGO feed mapping');
  if (registryStatCount > 0 && !espnRoster) notes.push('registry-supported without ESPN roster mapping');
  if (registryStatCount > 0 && !theOddsSport) notes.push('registry-supported without The Odds sport mapping');
  if (registryStatCount > 0 && theOddsPropStatCount === 0) notes.push('registry-supported without The Odds prop market coverage');
  if (registryStatCount > 0 && theOddsPropStatCount > 0 && theOddsPropStatCount < registryStatCount) {
    notes.push(`partial The Odds prop coverage (${theOddsPropStatCount}/${registryStatCount})`);
  }

  return {
    league,
    seeded,
    sgoFeed,
    espnRoster,
    theOddsSport,
    registryStatCount,
    theOddsPropStatCount,
    endToEndReady: registryStatCount > 0 && seeded && sgoFeed && espnRoster && theOddsSport && theOddsPropStatCount > 0,
    notes,
  };
}

export function buildLeagueCoverageAuditReport(auditedAt: string = new Date().toISOString()): LeagueCoverageAuditReport {
  const leagues = getCandidateLeagues().map(buildLeagueCoverageEntry);

  return {
    auditedAt,
    summary: {
      totalLeagues: leagues.length,
      registryLeagues: leagues.filter((league) => league.registryStatCount > 0).length,
      seededLeagues: leagues.filter((league) => league.seeded).length,
      endToEndReadyLeagues: leagues.filter((league) => league.endToEndReady).length,
      rosterGapLeagues: leagues.filter((league) => league.notes.includes('registry-supported without ESPN roster mapping')).length,
      partialTheOddsPropCoverageLeagues: leagues.filter((league) => league.notes.some((note) => note.startsWith('partial The Odds prop coverage'))).length,
    },
    leagues,
  };
}

export function renderLeagueCoverageAuditMarkdown(report: LeagueCoverageAuditReport): string {
  const summaryLines = [
    `- Total leagues in matrix: ${report.summary.totalLeagues}`,
    `- Registry-backed prop leagues: ${report.summary.registryLeagues}`,
    `- Active seeded leagues: ${report.summary.seededLeagues}`,
    `- End-to-end ready leagues: ${report.summary.endToEndReadyLeagues}`,
    `- Registry leagues missing ESPN roster coverage: ${report.summary.rosterGapLeagues}`,
    `- Registry leagues with partial The Odds prop coverage: ${report.summary.partialTheOddsPropCoverageLeagues}`,
  ];

  const tableLines = [
    '| League | Seeded | SGO | ESPN | The Odds sport | Registry stats | The Odds prop stats | Ready | Notes |',
    '| --- | --- | --- | --- | --- | --- | --- | --- | --- |',
    ...report.leagues.map((league) => [
      league.league,
      league.seeded ? 'yes' : 'no',
      league.sgoFeed ? 'yes' : 'no',
      league.espnRoster ? 'yes' : 'no',
      league.theOddsSport ? 'yes' : 'no',
      String(league.registryStatCount),
      String(league.theOddsPropStatCount),
      league.endToEndReady ? 'yes' : 'no',
      league.notes.join('; ') || '-',
    ].map((value) => String(value).replace(/\|/g, '\\|')).join(' | ')).map((line) => `| ${line} |`),
  ];

  return [
    '# League Coverage Audit',
    '',
    `Audited at: ${report.auditedAt}`,
    '',
    '## Summary',
    '',
    ...summaryLines,
    '',
    '## Matrix',
    '',
    ...tableLines,
    '',
  ].join('\n');
}
