export type AppConfig = {
  saveFolder: string | null;
  primarySaveFile: string | null;
  activeDynastyId: string | null;
};

export type ConfigPatch = Partial<AppConfig>;

export type SourcePointer = {
  table: string;
  uniqueId: number;
  tableId: number;
  row: number;
};

export type StatPayload = Record<string, string | number | boolean | null>;

export type AiContentType =
  | "article"
  | "recap"
  | "headline"
  | "social"
  | "grade_explanation";

export type AiGenerationMode = "save_only" | "screenshot_enriched";

export type AiContentModelMap = Partial<Record<AiContentType, string>>;

export type AiSettings = {
  baseUrl: string;
  model: string;
  apiKeyConfigured: boolean;
  contentModels: AiContentModelMap;
  promptPackId: string;
  disabledPersonalityIds: string[];
};

export type AiSettingsPatch = {
  baseUrl?: string;
  model?: string;
  apiKey?: string | null;
  contentModels?: AiContentModelMap;
  promptPackId?: string;
  disabledPersonalityIds?: string[];
};

export type AiConnectionResult = {
  ok: boolean;
  baseUrl: string;
  availableModels: string[];
  message: string;
};

export type AiPersonality = {
  id: string;
  name: string;
  role: "beat_reporter" | "national_analyst" | "fan";
  voice: string;
  enabled: boolean;
};

export type AiPromptPack = {
  id: string;
  name: string;
  description: string;
  personalities: AiPersonality[];
};

export type AiPromptTemplate = {
  id: number;
  dynastyId: string | null;
  packId: string;
  packName: string;
  contentType: AiContentType;
  mode: AiGenerationMode;
  name: string;
  template: string;
  isCustom: boolean;
  sourceTemplateId: number | null;
  updatedAt: string;
};

export type AiPlayerGradeEvidence = {
  playerRow: number;
  playerName: string;
  teamLabel: string;
  position: string | null;
  role: string;
  score: number;
  gradeLabel: string;
  line: string;
  factors: string[];
};

export type AiGenerateRequest = {
  snapshotId: number;
  gameRow: number;
  contentType: AiContentType;
  promptTemplateId?: number | null;
  gradeEvidence?: AiPlayerGradeEvidence[];
};

export type AiGeneratedArtifact = {
  id: number;
  dynastyId: string;
  snapshotId: number;
  gameRow: number;
  contentType: AiContentType;
  mode: AiGenerationMode;
  promptTemplateId: number;
  providerBaseUrl: string;
  model: string;
  renderedPrompt: string;
  evidence: Record<string, unknown>;
  content: Record<string, unknown>;
  createdAt: string;
  updatedAt: string;
};

export type CalendarSnapshot = {
  stage: string | null;
  weekType: string | null;
  week: number | null;
  seasonYear: number | null;
  dynastyYear: number | null;
  offseasonStage: number | null;
  offseasonAdvances: number | null;
};

export type TeamSummary = {
  row: number;
  teamIndex: number | null;
  displayName: string;
  shortName: string | null;
  nickName: string | null;
  conferenceRow: number | null;
  conferenceName: string | null;
  rank: number | null;
  mediaRank: number | null;
  coachesRank: number | null;
  cfpRank: number | null;
  prestige: number | null;
  prestigeRank: number | null;
  rivalTeamRows: number[];
  colors: {
    primary: string | null;
    secondary: string | null;
  };
  source: SourcePointer;
};

export type ConferenceSummary = {
  row: number;
  name: string;
  enumName: string | null;
  teamRows: number[];
  source: SourcePointer;
};

export type CoachSummary = {
  row: number;
  name: string | null;
  firstName: string | null;
  lastName: string | null;
  role: string | null;
  teamIndex: number | null;
  teamRow: number | null;
  level: number | null;
  prestige: string | null;
  prestigeScore: number | null;
  contractStatus: string | null;
  jobSecurity: string | null;
  isUserControlled: boolean;
  source: SourcePointer;
};

export type UserTeamSummary = {
  team: TeamSummary | null;
  coach: CoachSummary | null;
};

export type PlayerSummary = {
  row: number;
  firstName: string | null;
  lastName: string | null;
  displayName: string;
  position: string | null;
  jerseyNumber: number | null;
  schoolYear: string | null;
  overall: number | null;
  teamIndex: number | null;
  teamRow: number | null;
  rosterTeamRow: number | null;
  source: SourcePointer;
};

export type GameTeamStatsSummary = {
  gameRow: number;
  teamRow: number | null;
  side: "home" | "away";
  stats: StatPayload;
  source: SourcePointer;
};

export type GamePlayerStatsSummary = {
  gameRow: number;
  playerRow: number;
  playerName: string;
  teamRow: number | null;
  opponentTeamRow: number | null;
  statGroup: string;
  stats: StatPayload;
  source: SourcePointer;
};

export type GameSummary = {
  row: number;
  seasonYear: number | null;
  week: number | null;
  weekType: string | null;
  gameNumber: number | null;
  status: string | null;
  homeTeam: TeamSummary | null;
  awayTeam: TeamSummary | null;
  homeScore: number | null;
  awayScore: number | null;
  quarterScores: {
    home: [number | null, number | null, number | null, number | null];
    away: [number | null, number | null, number | null, number | null];
    homeOvertime: number | null;
    awayOvertime: number | null;
  };
  isSimmed: boolean | null;
  isGameOfTheWeek: boolean | null;
  isMajorGame: boolean;
  majorGameReasons: string[];
  attendance: number | null;
  weather: string | null;
  source: SourcePointer;
};

export type ImportProbeResult = {
  sourceFileName: string;
  sourceHash: string;
  archivePath: string;
  openedAt: string;
  dynastyId: string | null;
  schema: {
    gameYear: number | null;
    gameType: string | null;
    major: number | null;
    minor: number | null;
  };
  tableCount: number;
  calendar: CalendarSnapshot | null;
  userTeam: UserTeamSummary | null;
  conferences: ConferenceSummary[];
  coaches: CoachSummary[];
  teams: TeamSummary[];
  players: PlayerSummary[];
  games: GameSummary[];
  teamGameStats: GameTeamStatsSummary[];
  playerGameStats: GamePlayerStatsSummary[];
  validation: {
    lsuAuburn?: {
      found: boolean;
      gameRow: number | null;
      scoreMatched: boolean;
      houstonAndersonMatched: boolean;
      julianReeseMatched: boolean;
      notes: string[];
    };
  };
  importStatus?: {
    snapshotId: number | null;
    imported: boolean;
    duplicate: boolean;
    databasePath: string | null;
  };
  diagnostics: string[];
};

export type ScreenshotType =
  | "unknown"
  | "highlight_list"
  | "passing_stats"
  | "rushing_stats"
  | "receiving_stats";

export type ScreenshotRecord = {
  id: number;
  dynastyId: string | null;
  snapshotId: number | null;
  originalFileName: string;
  storedPath: string;
  fileHash: string;
  screenshotType: ScreenshotType;
  importedAt: string;
};

export type ScreenshotImportResult = {
  imported: ScreenshotRecord[];
  duplicates: ScreenshotRecord[];
};

export type PlayHighlightRecord = {
  id: number;
  dynastyId: string | null;
  snapshotId: number | null;
  gameRow: number;
  screenshotId: number;
  extractionId: number;
  sequence: number;
  period: string | null;
  clock: string | null;
  team: string | null;
  summary: string;
  score: string | null;
  rawText: string;
  approvedAt: string;
};

export type ScreenshotExtractionStatus = "pending" | "completed" | "failed";

export type ScreenshotExtractionArtifact = {
  zoneKey: string;
  label: string;
  purpose: "context" | "table" | "rows";
  path: string;
  x: number;
  y: number;
  width: number;
  height: number;
};

export type ScreenshotExtractionPayload = {
  image?: {
    width: number;
    height: number;
  };
  artifacts?: ScreenshotExtractionArtifact[];
  ocr?: {
    engine: "tesseract.js";
    language: string;
    completedAt: string;
    zones: ScreenshotOcrZoneResult[];
  };
  rawRows?: ScreenshotParsedRow[];
  rows?: ScreenshotParsedRow[];
  approval?: ScreenshotExtractionApproval | null;
  text?: string;
};

export type ScreenshotParsedRow = Record<string, string | number | null>;

export type ScreenshotExtractionApproval = {
  kind: "highlights" | "stats";
  gameRow: number;
  rowCount: number;
  approvedAt: string;
};

export type ScreenshotOcrZoneResult = {
  zoneKey: string;
  label: string;
  purpose: "context" | "table" | "rows";
  text: string;
  confidence: number | null;
};

export type ScreenshotExtractionRecord = {
  id: number;
  screenshotId: number;
  screenshotType: ScreenshotType;
  status: ScreenshotExtractionStatus;
  templateVersion: number;
  templateJson: Record<string, unknown>;
  extractedJson: ScreenshotExtractionPayload;
  errorMessage: string | null;
  createdAt: string;
  completedAt: string | null;
};

export type ScreenshotStatRecord = {
  id: number;
  dynastyId: string | null;
  snapshotId: number | null;
  gameRow: number;
  screenshotId: number;
  extractionId: number;
  rowType: "passing" | "rushing" | "receiving";
  playerName: string;
  team: string | null;
  rawRow: ScreenshotParsedRow;
  correctedRow: ScreenshotParsedRow;
  approvedAt: string;
};

export type DynastyLiveApi = {
  getConfig: () => Promise<AppConfig>;
  updateConfig: (patch: ConfigPatch) => Promise<AppConfig>;
  selectSaveFolder: () => Promise<AppConfig>;
  selectSaveFile: () => Promise<AppConfig>;
  importLatest: () => Promise<ImportProbeResult>;
  loadLatestSnapshot: () => Promise<ImportProbeResult | null>;
  importScreenshots: () => Promise<ScreenshotImportResult>;
  loadScreenshots: () => Promise<ScreenshotRecord[]>;
  updateScreenshotType: (
    id: number,
    screenshotType: ScreenshotType
  ) => Promise<ScreenshotRecord>;
  loadScreenshotExtractions: () => Promise<ScreenshotExtractionRecord[]>;
  createScreenshotExtraction: (
    screenshotId: number
  ) => Promise<ScreenshotExtractionRecord>;
  updateScreenshotExtractionText: (
    id: number,
    text: string
  ) => Promise<ScreenshotExtractionRecord>;
  updateScreenshotExtractionRows: (
    id: number,
    rows: ScreenshotParsedRow[]
  ) => Promise<ScreenshotExtractionRecord>;
  runScreenshotExtractionOcr: (
    id: number
  ) => Promise<ScreenshotExtractionRecord>;
  parseScreenshotExtractionRows: (
    id: number,
    targetGameRow?: number | null
  ) => Promise<ScreenshotExtractionRecord>;
  approveScreenshotHighlights: (
    extractionId: number,
    gameRow: number,
    snapshotId: number | null
  ) => Promise<PlayHighlightRecord[]>;
  approveScreenshotStats: (
    extractionId: number,
    gameRow: number,
    snapshotId: number | null
  ) => Promise<ScreenshotStatRecord[]>;
  loadPlayHighlights: (
    snapshotId: number | null,
    gameRow: number | null
  ) => Promise<PlayHighlightRecord[]>;
  loadScreenshotStats: (
    snapshotId: number | null,
    gameRow: number | null
  ) => Promise<ScreenshotStatRecord[]>;
  getAiSettings: () => Promise<AiSettings>;
  updateAiSettings: (patch: AiSettingsPatch) => Promise<AiSettings>;
  testAiConnection: () => Promise<AiConnectionResult>;
  loadAiPromptPacks: () => Promise<AiPromptPack[]>;
  loadAiPromptTemplates: () => Promise<AiPromptTemplate[]>;
  saveAiPromptTemplate: (
    id: number,
    template: string
  ) => Promise<AiPromptTemplate>;
  generateAiArtifact: (
    request: AiGenerateRequest
  ) => Promise<AiGeneratedArtifact>;
  loadAiArtifacts: (
    snapshotId: number,
    gameRow: number
  ) => Promise<AiGeneratedArtifact[]>;
  updateAiArtifact: (
    id: number,
    content: Record<string, unknown>
  ) => Promise<AiGeneratedArtifact>;
};
