import { integer, pgTable, varchar, uuid, timestamp, pgEnum, boolean, text, date, decimal, uniqueIndex, jsonb } from "drizzle-orm/pg-core";
import { relations } from "drizzle-orm";

// Users table - synced from Clerk
export const users = pgTable("users", {
  id: uuid("id").primaryKey().defaultRandom(),
  clerkId: varchar("clerk_id", { length: 255 }).notNull().unique(),
  email: varchar("email", { length: 255 }).notNull(),
  username: varchar("username", { length: 255 }),
  displayName: varchar("display_name", { length: 255 }),
  firstName: varchar("first_name", { length: 255 }),
  lastName: varchar("last_name", { length: 255 }),
  imageUrl: varchar("image_url", { length: 512 }),
  isAdmin: boolean("is_admin").notNull().default(false),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

// Fantasy League Tables
export const seasonStatusEnum = pgEnum("season_status", [
  "pre_draft",
  "draft",
  "active",
  "completed",
]);

// Sports Tables - Enums
export const sportTypeEnum = pgEnum("sport_type", ["team", "individual"]);

export const sportsSeasonStatusEnum = pgEnum("sports_season_status", [
  "upcoming",
  "active",
  "completed",
]);

export const scoringTypeEnum = pgEnum("scoring_type", [
  "playoffs",
  "regular_season",
  "majors",
]);

export const scoringPatternEnum = pgEnum("scoring_pattern", [
  "playoff_bracket",
  "season_standings",
  "qualifying_points",
]);

export const eventTypeEnum = pgEnum("event_type", [
  "playoff_game",
  "major_tournament",
  "final_standings",
  "schedule_event",
]);

export const pickedByTypeEnum = pgEnum("picked_by_type", [
  "owner",
  "commissioner",
  "admin",
  "auto",
]);

export const autodraftModeEnum = pgEnum("autodraft_mode", [
  "next_pick",
  "while_on",
]);

export const draftTimerModeEnum = pgEnum("draft_timer_mode", [
  "chess_clock",
  "standard",
]);

export const probabilitySourceEnum = pgEnum("probability_source", [
  "manual",
  "futures_odds",
  "elo_simulation",
  "performance_model",
]);

export const simulationStatusEnum = pgEnum("simulation_status", [
  "idle",
  "running",
  "failed",
]);

export const simulatorTypeEnum = pgEnum("simulator_type", [
  "f1_standings",
  "indycar_standings",
  "golf_qualifying_points",
  "playoff_bracket",
  "ucl_bracket",
  "ncaam_bracket",
  "ncaaw_bracket",
  "nba_bracket",
  "nhl_bracket",
  "afl_bracket",
  "snooker_bracket",
  "tennis_qualifying_points",
]);

export const playoffMatchGameStatusEnum = pgEnum("playoff_match_game_status", [
  "scheduled",
  "complete",
  "postponed",
]);

export const leagues = pgTable("leagues", {
  id: uuid("id").primaryKey().defaultRandom(),
  name: varchar("name", { length: 255 }).notNull(),
  createdBy: varchar("created_by", { length: 255 }).notNull(), // Clerk user ID
  currentSeasonId: uuid("current_season_id"), // References the active season
  isPublicDraftBoard: boolean("is_public_draft_board").notNull().default(false),
  discordWebhookUrl: text("discord_webhook_url"),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

export const seasonTemplates = pgTable("season_templates", {
  id: uuid("id").primaryKey().defaultRandom(),
  name: varchar("name", { length: 255 }).notNull(),
  description: text("description"),
  year: integer("year").notNull(),
  isActive: boolean("is_active").notNull().default(true),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

export const seasons = pgTable("seasons", {
  id: uuid("id").primaryKey().defaultRandom(),
  leagueId: uuid("league_id")
    .notNull()
    .references(() => leagues.id, { onDelete: "cascade" }),
  year: integer("year").notNull(),
  status: seasonStatusEnum("status").notNull().default("pre_draft"),
  templateId: uuid("template_id")
    .references(() => seasonTemplates.id, { onDelete: "set null" }),
  draftRounds: integer("draft_rounds").notNull().default(20),
  flexSpots: integer("flex_spots").notNull().default(0),
  draftDateTime: timestamp("draft_date_time"),
  draftInitialTime: integer("draft_initial_time").notNull().default(120), // seconds
  draftIncrementTime: integer("draft_increment_time").notNull().default(30), // seconds
  draftTimerMode: draftTimerModeEnum("draft_timer_mode").notNull().default("chess_clock"),
  currentPickNumber: integer("current_pick_number").default(1),
  draftStartedAt: timestamp("draft_started_at"),
  draftPaused: boolean("draft_paused").notNull().default(false),
  inviteCode: varchar("invite_code", { length: 20 }).notNull().unique(),
  // Scoring configuration (8 values for 1st through 8th)
  pointsFor1st: integer("points_for_1st").notNull().default(100),
  pointsFor2nd: integer("points_for_2nd").notNull().default(70),
  pointsFor3rd: integer("points_for_3rd").notNull().default(50),
  pointsFor4th: integer("points_for_4th").notNull().default(40),
  pointsFor5th: integer("points_for_5th").notNull().default(25),
  pointsFor6th: integer("points_for_6th").notNull().default(25),
  pointsFor7th: integer("points_for_7th").notNull().default(15),
  pointsFor8th: integer("points_for_8th").notNull().default(15),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

export const teams = pgTable("teams", {
  id: uuid("id").primaryKey().defaultRandom(),
  seasonId: uuid("season_id")
    .notNull()
    .references(() => seasons.id, { onDelete: "cascade" }),
  name: varchar("name", { length: 255 }).notNull(),
  logoUrl: varchar("logo_url", { length: 512 }),
  ownerId: varchar("owner_id", { length: 255 }), // Clerk user ID, nullable
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

export const draftSlots = pgTable("draft_slots", {
  id: uuid("id").primaryKey().defaultRandom(),
  seasonId: uuid("season_id")
    .notNull()
    .references(() => seasons.id, { onDelete: "cascade" }),
  teamId: uuid("team_id")
    .notNull()
    .references(() => teams.id, { onDelete: "cascade" }),
  draftOrder: integer("draft_order").notNull(),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

export const draftPicks = pgTable("draft_picks", {
  id: uuid("id").primaryKey().defaultRandom(),
  seasonId: uuid("season_id")
    .notNull()
    .references(() => seasons.id, { onDelete: "cascade" }),
  teamId: uuid("team_id")
    .notNull()
    .references(() => teams.id, { onDelete: "cascade" }),
  participantId: uuid("participant_id")
    .notNull()
    .references(() => participants.id, { onDelete: "cascade" }),
  pickNumber: integer("pick_number").notNull(),
  round: integer("round").notNull(),
  pickInRound: integer("pick_in_round").notNull(),
  pickedByUserId: varchar("picked_by_user_id", { length: 255 }).notNull(), // Clerk user ID
  pickedByType: pickedByTypeEnum("picked_by_type").notNull(),
  timeUsed: integer("time_used").notNull().default(0), // team's time bank (seconds) at the moment the pick was made
  createdAt: timestamp("created_at").defaultNow().notNull(),
}, (t) => ({
  // Prevents two concurrent picks from landing in the same slot
  uniquePickSlot: uniqueIndex("draft_picks_season_pick_unique").on(t.seasonId, t.pickNumber),
}));

export const draftQueue = pgTable("draft_queue", {
  id: uuid("id").primaryKey().defaultRandom(),
  seasonId: uuid("season_id")
    .notNull()
    .references(() => seasons.id, { onDelete: "cascade" }),
  teamId: uuid("team_id")
    .notNull()
    .references(() => teams.id, { onDelete: "cascade" }),
  participantId: uuid("participant_id")
    .notNull()
    .references(() => participants.id, { onDelete: "cascade" }),
  queuePosition: integer("queue_position").notNull(),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

export const draftTimers = pgTable("draft_timers", {
  id: uuid("id").primaryKey().defaultRandom(),
  seasonId: uuid("season_id")
    .notNull()
    .references(() => seasons.id, { onDelete: "cascade" }),
  teamId: uuid("team_id")
    .notNull()
    .references(() => teams.id, { onDelete: "cascade" }),
  timeRemaining: integer("time_remaining").notNull(), // seconds
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

export const autodraftSettings = pgTable("autodraft_settings", {
  id: uuid("id").primaryKey().defaultRandom(),
  seasonId: uuid("season_id")
    .notNull()
    .references(() => seasons.id, { onDelete: "cascade" }),
  teamId: uuid("team_id")
    .notNull()
    .references(() => teams.id, { onDelete: "cascade" }),
  isEnabled: boolean("is_enabled").notNull().default(false),
  mode: autodraftModeEnum("mode").notNull().default("next_pick"),
  queueOnly: boolean("queue_only").notNull().default(false),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

export const commissioners = pgTable("commissioners", {
  id: uuid("id").primaryKey().defaultRandom(),
  leagueId: uuid("league_id")
    .notNull()
    .references(() => leagues.id, { onDelete: "cascade" }),
  userId: varchar("user_id", { length: 255 }).notNull(), // Clerk user ID
  createdAt: timestamp("created_at").defaultNow().notNull(),
});

// Sports Tables
export const sports = pgTable("sports", {
  id: uuid("id").primaryKey().defaultRandom(),
  name: varchar("name", { length: 255 }).notNull(),
  type: sportTypeEnum("type").notNull(),
  slug: varchar("slug", { length: 255 }).notNull().unique(),
  description: text("description"),
  iconUrl: varchar("icon_url", { length: 255 }), // Filename of icon in /public/sports-icons/
  simulatorType: simulatorTypeEnum("simulator_type"),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

export const sportsSeasons = pgTable("sports_seasons", {
  id: uuid("id").primaryKey().defaultRandom(),
  sportId: uuid("sport_id")
    .notNull()
    .references(() => sports.id, { onDelete: "cascade" }),
  name: varchar("name", { length: 255 }).notNull(),
  year: integer("year").notNull(),
  startDate: date("start_date"),
  endDate: date("end_date"),
  status: sportsSeasonStatusEnum("status").notNull().default("upcoming"),
  scoringType: scoringTypeEnum("scoring_type").notNull(),
  // New scoring pattern field (replaces/augments scoringType)
  scoringPattern: scoringPatternEnum("scoring_pattern"),
  // For qualifying points sports
  totalMajors: integer("total_majors"),
  majorsCompleted: integer("majors_completed").notNull().default(0),
  qualifyingPointsFinalized: boolean("qualifying_points_finalized").notNull().default(false),
  // EV Calibration parameters (for Elo-based probability generation)
  eloCalibrationExponent: decimal("elo_calibration_exponent", { precision: 3, scale: 2 }), // e.g., 0.33
  eloMinRating: integer("elo_min_rating").default(1250),
  eloMaxRating: integer("elo_max_rating").default(1750),
  // Simulation status (prevents concurrent simulation runs)
  simulationStatus: simulationStatusEnum("simulation_status").notNull().default("idle"),
  // Controls whether this sport season appears in league creation/settings
  isDraftable: boolean("is_draftable").notNull().default(true),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

export const participants = pgTable("participants", {
  id: uuid("id").primaryKey().defaultRandom(),
  sportsSeasonId: uuid("sports_season_id")
    .notNull()
    .references(() => sportsSeasons.id, { onDelete: "cascade" }),
  name: varchar("name", { length: 255 }).notNull(),
  shortName: varchar("short_name", { length: 100 }),
  externalId: varchar("external_id", { length: 255 }),
  expectedValue: decimal("expected_value", { precision: 10, scale: 4 }).notNull().default("0"),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

export const seasonTemplateSports = pgTable("season_template_sports", {
  id: uuid("id").primaryKey().defaultRandom(),
  templateId: uuid("template_id")
    .notNull()
    .references(() => seasonTemplates.id, { onDelete: "cascade" }),
  sportsSeasonId: uuid("sports_season_id")
    .notNull()
    .references(() => sportsSeasons.id, { onDelete: "cascade" }),
  createdAt: timestamp("created_at").defaultNow().notNull(),
});

export const seasonSports = pgTable("season_sports", {
  id: uuid("id").primaryKey().defaultRandom(),
  seasonId: uuid("season_id")
    .notNull()
    .references(() => seasons.id, { onDelete: "cascade" }),
  sportsSeasonId: uuid("sports_season_id")
    .notNull()
    .references(() => sportsSeasons.id, { onDelete: "cascade" }),
  createdAt: timestamp("created_at").defaultNow().notNull(),
});

export const participantResults = pgTable("participant_results", {
  id: uuid("id").primaryKey().defaultRandom(),
  participantId: uuid("participant_id")
    .notNull()
    .references(() => participants.id, { onDelete: "cascade" }),
  sportsSeasonId: uuid("sports_season_id")
    .notNull()
    .references(() => sportsSeasons.id, { onDelete: "cascade" }),
  finalPosition: integer("final_position"),
  isPartialScore: boolean("is_partial_score").notNull().default(false),
  qualifyingPoints: decimal("qualifying_points", { precision: 10, scale: 2 }),
  notes: text("notes"),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

// Scoring System Tables

// Individual scoring events (games, tournaments, races)
export const scoringEvents = pgTable("scoring_events", {
  id: uuid("id").primaryKey().defaultRandom(),
  sportsSeasonId: uuid("sports_season_id")
    .notNull()
    .references(() => sportsSeasons.id, { onDelete: "cascade" }),
  name: varchar("name", { length: 255 }).notNull(), // "2024 Masters", "Super Bowl LIX", etc.
  eventDate: date("event_date"),
  eventStartsAt: timestamp("event_starts_at", { withTimezone: true }),
  eventType: eventTypeEnum("event_type").notNull(),
  // For playoff events
  playoffRound: varchar("playoff_round", { length: 50 }), // "Quarterfinals", "Semifinals", "Finals"
  // For qualifying events
  isQualifyingEvent: boolean("is_qualifying_event").notNull().default(false),
  // Template system (Phase 2.6)
  bracketTemplateId: varchar("bracket_template_id", { length: 50 }), // "ncaa_68", "nfl_14", "simple_16", etc.
  scoringStartsAtRound: varchar("scoring_starts_at_round", { length: 50 }), // "Elite Eight", "Quarterfinals", etc.
  // Per-event region config for NCAA-style brackets (overrides template defaults)
  bracketRegionConfig: jsonb("bracket_region_config"), // BracketRegion[] | null
  isComplete: boolean("is_complete").notNull().default(false),
  completedAt: timestamp("completed_at"),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

// Results for participants in specific events
export const eventResults = pgTable("event_results", {
  id: uuid("id").primaryKey().defaultRandom(),
  scoringEventId: uuid("scoring_event_id")
    .notNull()
    .references(() => scoringEvents.id, { onDelete: "cascade" }),
  participantId: uuid("participant_id")
    .notNull()
    .references(() => participants.id, { onDelete: "cascade" }),
  // Placement in this specific event
  placement: integer("placement"),
  // For qualifying events: QP awarded in this event
  qualifyingPointsAwarded: decimal("qualifying_points_awarded", { precision: 10, scale: 2 }),
  // For playoff events: eliminated or advanced
  eliminated: boolean("eliminated"),
  // Raw sport-specific data (optional)
  rawScore: decimal("raw_score", { precision: 10, scale: 2 }), // strokes, points, time, etc.
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

// Playoff bracket matches (for display and tracking)
export const playoffMatches = pgTable("playoff_matches", {
  id: uuid("id").primaryKey().defaultRandom(),
  scoringEventId: uuid("scoring_event_id")
    .notNull()
    .references(() => scoringEvents.id, { onDelete: "cascade" }),
  round: varchar("round", { length: 50 }).notNull(), // "Quarterfinals", "Semifinals", "Finals"
  matchNumber: integer("match_number").notNull(), // 1, 2, 3, 4 (for QF); 1, 2 (for SF); 1 (for F)
  participant1Id: uuid("participant1_id").references(() => participants.id, { onDelete: "set null" }),
  participant2Id: uuid("participant2_id").references(() => participants.id, { onDelete: "set null" }),
  winnerId: uuid("winner_id").references(() => participants.id, { onDelete: "set null" }),
  loserId: uuid("loser_id").references(() => participants.id, { onDelete: "set null" }),
  isComplete: boolean("is_complete").notNull().default(false),
  // Optional detailed data
  participant1Score: decimal("participant1_score", { precision: 10, scale: 2 }),
  participant2Score: decimal("participant2_score", { precision: 10, scale: 2 }),
  // Template system (Phase 2.6)
  isScoring: boolean("is_scoring").notNull().default(true), // Does this match affect fantasy points?
  templateRound: varchar("template_round", { length: 50 }), // "First Four", "Round of 64", "Elite Eight", etc.
  seedInfo: varchar("seed_info", { length: 50 }), // "1 vs 16", "11a vs 11b", etc. (for display)
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

// Individual games within a playoff matchup (e.g., NBA 7-game series games)
export const playoffMatchGames = pgTable("playoff_match_games", {
  id: uuid("id").primaryKey().defaultRandom(),
  playoffMatchId: uuid("playoff_match_id")
    .notNull()
    .references(() => playoffMatches.id, { onDelete: "cascade" }),
  gameNumber: integer("game_number").notNull(),
  scheduledAt: timestamp("scheduled_at"),
  status: playoffMatchGameStatusEnum("status").notNull().default("scheduled"),
  participant1Score: decimal("participant1_score", { precision: 10, scale: 2 }),
  participant2Score: decimal("participant2_score", { precision: 10, scale: 2 }),
  winnerId: uuid("winner_id").references(() => participants.id, { onDelete: "set null" }),
  notes: text("notes"),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

// Moneyline odds per participant per matchup (single record per participant, overwritten on update)
export const playoffMatchOdds = pgTable("playoff_match_odds", {
  id: uuid("id").primaryKey().defaultRandom(),
  playoffMatchId: uuid("playoff_match_id")
    .notNull()
    .references(() => playoffMatches.id, { onDelete: "cascade" }),
  participantId: uuid("participant_id")
    .notNull()
    .references(() => participants.id, { onDelete: "cascade" }),
  moneylineOdds: integer("moneyline_odds"), // American format e.g. -110, +150
  impliedProbability: decimal("implied_probability", { precision: 6, scale: 4 }),
  oddsSource: varchar("odds_source", { length: 100 }),
  recordedAt: timestamp("recorded_at").defaultNow().notNull(),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

// Aggregated participant qualifying points (for qualifying_points sports)
export const participantQualifyingTotals = pgTable("participant_qualifying_totals", {
  id: uuid("id").primaryKey().defaultRandom(),
  participantId: uuid("participant_id")
    .notNull()
    .references(() => participants.id, { onDelete: "cascade" }),
  sportsSeasonId: uuid("sports_season_id")
    .notNull()
    .references(() => sportsSeasons.id, { onDelete: "cascade" }),
  totalQualifyingPoints: decimal("total_qualifying_points", { precision: 10, scale: 2 }).notNull().default("0"),
  eventsScored: integer("events_scored").notNull().default(0),
  // After finalization
  finalRanking: integer("final_ranking"), // 1-8 based on QP totals
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

// Configurable qualifying point values per sports season
export const qualifyingPointConfig = pgTable("qualifying_point_config", {
  id: uuid("id").primaryKey().defaultRandom(),
  sportsSeasonId: uuid("sports_season_id")
    .notNull()
    .references(() => sportsSeasons.id, { onDelete: "cascade" }),
  placement: integer("placement").notNull(), // 1-16
  points: decimal("points", { precision: 10, scale: 2 }).notNull(),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

// Team scores aggregated by sport season
export const teamSportScores = pgTable("team_sport_scores", {
  id: uuid("id").primaryKey().defaultRandom(),
  teamId: uuid("team_id")
    .notNull()
    .references(() => teams.id, { onDelete: "cascade" }),
  sportsSeasonId: uuid("sports_season_id")
    .notNull()
    .references(() => sportsSeasons.id, { onDelete: "cascade" }),
  totalPoints: decimal("total_points", { precision: 10, scale: 2 }).notNull().default("0"),
  participantsCompleted: integer("participants_completed").notNull().default(0), // How many picks have finished
  participantsTotal: integer("participants_total").notNull().default(0), // Total picks for this sport
  calculatedAt: timestamp("calculated_at").defaultNow().notNull(),
});

// Overall team standings (snapshot-based for movement tracking)
export const teamStandings = pgTable("team_standings", {
  id: uuid("id").primaryKey().defaultRandom(),
  teamId: uuid("team_id")
    .notNull()
    .references(() => teams.id, { onDelete: "cascade" }),
  seasonId: uuid("season_id")
    .notNull()
    .references(() => seasons.id, { onDelete: "cascade" }),
  totalPoints: decimal("total_points", { precision: 10, scale: 2 }).notNull().default("0"),
  currentRank: integer("current_rank").notNull(),
  previousRank: integer("previous_rank"), // For movement indicators
  // Tiebreaker data
  firstPlaceCount: integer("first_place_count").notNull().default(0),
  secondPlaceCount: integer("second_place_count").notNull().default(0),
  thirdPlaceCount: integer("third_place_count").notNull().default(0),
  fourthPlaceCount: integer("fourth_place_count").notNull().default(0),
  fifthPlaceCount: integer("fifth_place_count").notNull().default(0),
  sixthPlaceCount: integer("sixth_place_count").notNull().default(0),
  seventhPlaceCount: integer("seventh_place_count").notNull().default(0),
  eighthPlaceCount: integer("eighth_place_count").notNull().default(0),
  participantsRemaining: integer("participants_remaining").notNull().default(0), // Not yet finished
  // Expected value tracking (Phase 5.4)
  actualPoints: decimal("actual_points", { precision: 10, scale: 2 }), // Points from finished participants
  projectedPoints: decimal("projected_points", { precision: 10, scale: 2 }), // actualPoints + EVs of unfinished
  participantsFinished: integer("participants_finished"), // Count of finished participants
  calculatedAt: timestamp("calculated_at").defaultNow().notNull(),
});

// Daily standings snapshots for historical tracking
export const teamStandingsSnapshots = pgTable("team_standings_snapshots", {
  id: uuid("id").primaryKey().defaultRandom(),
  teamId: uuid("team_id")
    .notNull()
    .references(() => teams.id, { onDelete: "cascade" }),
  seasonId: uuid("season_id")
    .notNull()
    .references(() => seasons.id, { onDelete: "cascade" }),
  snapshotDate: date("snapshot_date").notNull(),
  totalPoints: decimal("total_points", { precision: 10, scale: 2 }).notNull().default("0"),
  rank: integer("rank").notNull(),
  // Tiebreaker data
  firstPlaceCount: integer("first_place_count").notNull().default(0),
  secondPlaceCount: integer("second_place_count").notNull().default(0),
  thirdPlaceCount: integer("third_place_count").notNull().default(0),
  fourthPlaceCount: integer("fourth_place_count").notNull().default(0),
  fifthPlaceCount: integer("fifth_place_count").notNull().default(0),
  sixthPlaceCount: integer("sixth_place_count").notNull().default(0),
  seventhPlaceCount: integer("seventh_place_count").notNull().default(0),
  eighthPlaceCount: integer("eighth_place_count").notNull().default(0),
  participantsRemaining: integer("participants_remaining").notNull().default(0),
  // Expected value tracking
  actualPoints: decimal("actual_points", { precision: 10, scale: 2 }), // Points from finished participants
  projectedPoints: decimal("projected_points", { precision: 10, scale: 2 }), // actualPoints + EVs of unfinished
  participantsFinished: integer("participants_finished"), // Count of finished participants
  createdAt: timestamp("created_at").defaultNow().notNull(),
}, (t) => ({
  uniqueTeamSeasonDate: uniqueIndex("team_standings_snapshots_unique").on(
    t.teamId, t.seasonId, t.snapshotDate
  ),
}));

// Expected value tracking (sports-season-specific)
export const participantExpectedValues = pgTable("participant_expected_values", {
  id: uuid("id").primaryKey().defaultRandom(),
  participantId: uuid("participant_id")
    .notNull()
    .references(() => participants.id, { onDelete: "cascade" }),
  sportsSeasonId: uuid("sports_season_id")
    .notNull()
    .references(() => sportsSeasons.id, { onDelete: "cascade" }),
  // Probability distribution (stored as fractions, e.g. 0.1550 = 15.5%)
  probFirst: decimal("prob_first", { precision: 6, scale: 4 }).notNull().default("0"),
  probSecond: decimal("prob_second", { precision: 6, scale: 4 }).notNull().default("0"),
  probThird: decimal("prob_third", { precision: 6, scale: 4 }).notNull().default("0"),
  probFourth: decimal("prob_fourth", { precision: 6, scale: 4 }).notNull().default("0"),
  probFifth: decimal("prob_fifth", { precision: 6, scale: 4 }).notNull().default("0"),
  probSixth: decimal("prob_sixth", { precision: 6, scale: 4 }).notNull().default("0"),
  probSeventh: decimal("prob_seventh", { precision: 6, scale: 4 }).notNull().default("0"),
  probEighth: decimal("prob_eighth", { precision: 6, scale: 4 }).notNull().default("0"),
  // Calculated EV
  expectedValue: decimal("expected_value", { precision: 10, scale: 4 }).notNull().default("0"),
  // Metadata
  source: probabilitySourceEnum("source").default("manual"), // How probabilities were generated
  sourceOdds: integer("source_odds"), // Original odds if source is futures_odds (American odds format)
  sourceElo: integer("source_elo"), // Raw Elo rating if source is elo-based simulator (e.g. snooker_bracket)
  calculatedAt: timestamp("calculated_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
}, (t) => ({
  uniqueParticipantSeason: uniqueIndex("participant_ev_participant_season_unique").on(
    t.participantId, t.sportsSeasonId
  ),
}));

// Tournament group stage tables (for FIFA World Cup style tournaments)
export const tournamentGroups = pgTable("tournament_groups", {
  id: uuid("id").primaryKey().defaultRandom(),
  scoringEventId: uuid("scoring_event_id")
    .notNull()
    .references(() => scoringEvents.id, { onDelete: "cascade" }),
  groupName: varchar("group_name", { length: 10 }).notNull(), // "A" through "L"
  createdAt: timestamp("created_at").defaultNow().notNull(),
});

export const tournamentGroupMembers = pgTable("tournament_group_members", {
  id: uuid("id").primaryKey().defaultRandom(),
  tournamentGroupId: uuid("tournament_group_id")
    .notNull()
    .references(() => tournamentGroups.id, { onDelete: "cascade" }),
  participantId: uuid("participant_id")
    .notNull()
    .references(() => participants.id, { onDelete: "cascade" }),
  eliminated: boolean("eliminated").notNull().default(false),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

// Participant season results (for F1 current points tracking during season)
export const participantSeasonResults = pgTable("participant_season_results", {
  id: uuid("id").primaryKey().defaultRandom(),
  participantId: uuid("participant_id")
    .notNull()
    .references(() => participants.id, { onDelete: "cascade" }),
  sportsSeasonId: uuid("sports_season_id")
    .notNull()
    .references(() => sportsSeasons.id, { onDelete: "cascade" }),
  currentPoints: decimal("current_points", { precision: 10, scale: 2 }).notNull().default("0"), // Current F1 championship points, etc.
  currentPosition: integer("current_position"), // Current standings position
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

// EV snapshots — historical record of participant EV over time (one per participant per sport season per day)
export const participantEvSnapshots = pgTable("participant_ev_snapshots", {
  id: uuid("id").primaryKey().defaultRandom(),
  participantId: uuid("participant_id")
    .notNull()
    .references(() => participants.id, { onDelete: "cascade" }),
  sportsSeasonId: uuid("sports_season_id")
    .notNull()
    .references(() => sportsSeasons.id, { onDelete: "cascade" }),
  snapshotDate: date("snapshot_date").notNull(),
  // Probability distribution (stored as fractions, e.g. 0.1550 = 15.5%)
  probFirst: decimal("prob_first", { precision: 5, scale: 2 }).notNull().default("0"),
  probSecond: decimal("prob_second", { precision: 5, scale: 2 }).notNull().default("0"),
  probThird: decimal("prob_third", { precision: 5, scale: 2 }).notNull().default("0"),
  probFourth: decimal("prob_fourth", { precision: 5, scale: 2 }).notNull().default("0"),
  probFifth: decimal("prob_fifth", { precision: 5, scale: 2 }).notNull().default("0"),
  probSixth: decimal("prob_sixth", { precision: 5, scale: 2 }).notNull().default("0"),
  probSeventh: decimal("prob_seventh", { precision: 5, scale: 2 }).notNull().default("0"),
  probEighth: decimal("prob_eighth", { precision: 5, scale: 2 }).notNull().default("0"),
  calculatedEV: decimal("calculated_ev", { precision: 10, scale: 4 }).notNull().default("0"),
  source: varchar("source", { length: 100 }).notNull(), // e.g. 'bracket_monte_carlo', 'f1_standings_model'
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
}, (t) => ({
  uniqueParticipantSeasonDate: uniqueIndex("participant_ev_snapshots_unique").on(
    t.participantId, t.sportsSeasonId, t.snapshotDate
  ),
}));

// Team EV snapshots — historical projected points per team per fantasy season per day
export const teamEvSnapshots = pgTable("team_ev_snapshots", {
  id: uuid("id").primaryKey().defaultRandom(),
  teamId: uuid("team_id")
    .notNull()
    .references(() => teams.id, { onDelete: "cascade" }),
  seasonId: uuid("season_id")
    .notNull()
    .references(() => seasons.id, { onDelete: "cascade" }),
  snapshotDate: date("snapshot_date").notNull(),
  projectedPoints: decimal("projected_points", { precision: 10, scale: 2 }).notNull().default("0"),
  actualPoints: decimal("actual_points", { precision: 10, scale: 2 }).notNull().default("0"),
  createdAt: timestamp("created_at").defaultNow().notNull(),
}, (t) => ({
  uniqueTeamSeasonDate: uniqueIndex("team_ev_snapshots_unique").on(
    t.teamId, t.seasonId, t.snapshotDate
  ),
}));

// Relations
export const sportsRelations = relations(sports, ({ many }) => ({
  sportsSeasons: many(sportsSeasons),
}));

export const sportsSeasonsRelations = relations(sportsSeasons, ({ one, many }) => ({
  sport: one(sports, {
    fields: [sportsSeasons.sportId],
    references: [sports.id],
  }),
  participants: many(participants),
  seasonTemplateSports: many(seasonTemplateSports),
  seasonSports: many(seasonSports),
  participantResults: many(participantResults),
  regularSeasonStandings: many(regularSeasonStandings),
  pendingStandingsMappings: many(pendingStandingsMappings),
}));

export const participantsRelations = relations(participants, ({ one, many }) => ({
  sportsSeason: one(sportsSeasons, {
    fields: [participants.sportsSeasonId],
    references: [sportsSeasons.id],
  }),
  results: many(participantResults),
  regularSeasonStandings: many(regularSeasonStandings),
}));

export const seasonTemplatesRelations = relations(seasonTemplates, ({ many }) => ({
  seasonTemplateSports: many(seasonTemplateSports),
  seasons: many(seasons),
}));

export const seasonTemplateSportsRelations = relations(seasonTemplateSports, ({ one }) => ({
  template: one(seasonTemplates, {
    fields: [seasonTemplateSports.templateId],
    references: [seasonTemplates.id],
  }),
  sportsSeason: one(sportsSeasons, {
    fields: [seasonTemplateSports.sportsSeasonId],
    references: [sportsSeasons.id],
  }),
}));

export const seasonsRelations = relations(seasons, ({ one, many }) => ({
  league: one(leagues, {
    fields: [seasons.leagueId],
    references: [leagues.id],
  }),
  template: one(seasonTemplates, {
    fields: [seasons.templateId],
    references: [seasonTemplates.id],
  }),
  teams: many(teams),
  seasonSports: many(seasonSports),
}));

export const seasonSportsRelations = relations(seasonSports, ({ one }) => ({
  season: one(seasons, {
    fields: [seasonSports.seasonId],
    references: [seasons.id],
  }),
  sportsSeason: one(sportsSeasons, {
    fields: [seasonSports.sportsSeasonId],
    references: [sportsSeasons.id],
  }),
}));

export const participantResultsRelations = relations(participantResults, ({ one }) => ({
  participant: one(participants, {
    fields: [participantResults.participantId],
    references: [participants.id],
  }),
  sportsSeason: one(sportsSeasons, {
    fields: [participantResults.sportsSeasonId],
    references: [sportsSeasons.id],
  }),
}));

export const teamsRelations = relations(teams, ({ one }) => ({
  season: one(seasons, {
    fields: [teams.seasonId],
    references: [seasons.id],
  }),
  draftSlot: one(draftSlots, {
    fields: [teams.id],
    references: [draftSlots.teamId],
  }),
}));

export const draftSlotsRelations = relations(draftSlots, ({ one }) => ({
  season: one(seasons, {
    fields: [draftSlots.seasonId],
    references: [seasons.id],
  }),
  team: one(teams, {
    fields: [draftSlots.teamId],
    references: [teams.id],
  }),
}));

export const draftPicksRelations = relations(draftPicks, ({ one }) => ({
  season: one(seasons, {
    fields: [draftPicks.seasonId],
    references: [seasons.id],
  }),
  team: one(teams, {
    fields: [draftPicks.teamId],
    references: [teams.id],
  }),
  participant: one(participants, {
    fields: [draftPicks.participantId],
    references: [participants.id],
  }),
}));

export const draftQueueRelations = relations(draftQueue, ({ one }) => ({
  season: one(seasons, {
    fields: [draftQueue.seasonId],
    references: [seasons.id],
  }),
  team: one(teams, {
    fields: [draftQueue.teamId],
    references: [teams.id],
  }),
  participant: one(participants, {
    fields: [draftQueue.participantId],
    references: [participants.id],
  }),
}));

export const autodraftSettingsRelations = relations(autodraftSettings, ({ one }) => ({
  season: one(seasons, {
    fields: [autodraftSettings.seasonId],
    references: [seasons.id],
  }),
  team: one(teams, {
    fields: [autodraftSettings.teamId],
    references: [teams.id],
  }),
}));

// Scoring System Relations

export const scoringEventsRelations = relations(scoringEvents, ({ one, many }) => ({
  sportsSeason: one(sportsSeasons, {
    fields: [scoringEvents.sportsSeasonId],
    references: [sportsSeasons.id],
  }),
  eventResults: many(eventResults),
  playoffMatches: many(playoffMatches),
  tournamentGroups: many(tournamentGroups),
}));

export const eventResultsRelations = relations(eventResults, ({ one }) => ({
  scoringEvent: one(scoringEvents, {
    fields: [eventResults.scoringEventId],
    references: [scoringEvents.id],
  }),
  participant: one(participants, {
    fields: [eventResults.participantId],
    references: [participants.id],
  }),
}));

export const playoffMatchesRelations = relations(playoffMatches, ({ one, many }) => ({
  scoringEvent: one(scoringEvents, {
    fields: [playoffMatches.scoringEventId],
    references: [scoringEvents.id],
  }),
  participant1: one(participants, {
    fields: [playoffMatches.participant1Id],
    references: [participants.id],
  }),
  participant2: one(participants, {
    fields: [playoffMatches.participant2Id],
    references: [participants.id],
  }),
  winner: one(participants, {
    fields: [playoffMatches.winnerId],
    references: [participants.id],
  }),
  loser: one(participants, {
    fields: [playoffMatches.loserId],
    references: [participants.id],
  }),
  games: many(playoffMatchGames),
  odds: many(playoffMatchOdds),
}));

export const playoffMatchGamesRelations = relations(playoffMatchGames, ({ one }) => ({
  match: one(playoffMatches, {
    fields: [playoffMatchGames.playoffMatchId],
    references: [playoffMatches.id],
  }),
  winner: one(participants, {
    fields: [playoffMatchGames.winnerId],
    references: [participants.id],
  }),
}));

export const playoffMatchOddsRelations = relations(playoffMatchOdds, ({ one }) => ({
  match: one(playoffMatches, {
    fields: [playoffMatchOdds.playoffMatchId],
    references: [playoffMatches.id],
  }),
  participant: one(participants, {
    fields: [playoffMatchOdds.participantId],
    references: [participants.id],
  }),
}));

export const participantQualifyingTotalsRelations = relations(participantQualifyingTotals, ({ one }) => ({
  participant: one(participants, {
    fields: [participantQualifyingTotals.participantId],
    references: [participants.id],
  }),
  sportsSeason: one(sportsSeasons, {
    fields: [participantQualifyingTotals.sportsSeasonId],
    references: [sportsSeasons.id],
  }),
}));

export const qualifyingPointConfigRelations = relations(qualifyingPointConfig, ({ one }) => ({
  sportsSeason: one(sportsSeasons, {
    fields: [qualifyingPointConfig.sportsSeasonId],
    references: [sportsSeasons.id],
  }),
}));

export const teamSportScoresRelations = relations(teamSportScores, ({ one }) => ({
  team: one(teams, {
    fields: [teamSportScores.teamId],
    references: [teams.id],
  }),
  sportsSeason: one(sportsSeasons, {
    fields: [teamSportScores.sportsSeasonId],
    references: [sportsSeasons.id],
  }),
}));

export const teamStandingsRelations = relations(teamStandings, ({ one }) => ({
  team: one(teams, {
    fields: [teamStandings.teamId],
    references: [teams.id],
  }),
  season: one(seasons, {
    fields: [teamStandings.seasonId],
    references: [seasons.id],
  }),
}));

export const teamStandingsSnapshotsRelations = relations(teamStandingsSnapshots, ({ one }) => ({
  team: one(teams, {
    fields: [teamStandingsSnapshots.teamId],
    references: [teams.id],
  }),
  season: one(seasons, {
    fields: [teamStandingsSnapshots.seasonId],
    references: [seasons.id],
  }),
}));

export const participantExpectedValuesRelations = relations(participantExpectedValues, ({ one }) => ({
  participant: one(participants, {
    fields: [participantExpectedValues.participantId],
    references: [participants.id],
  }),
  sportsSeason: one(sportsSeasons, {
    fields: [participantExpectedValues.sportsSeasonId],
    references: [sportsSeasons.id],
  }),
}));

export const participantSeasonResultsRelations = relations(participantSeasonResults, ({ one }) => ({
  participant: one(participants, {
    fields: [participantSeasonResults.participantId],
    references: [participants.id],
  }),
  sportsSeason: one(sportsSeasons, {
    fields: [participantSeasonResults.sportsSeasonId],
    references: [sportsSeasons.id],
  }),
}));

// Tournament Group Relations
export const tournamentGroupsRelations = relations(tournamentGroups, ({ one, many }) => ({
  scoringEvent: one(scoringEvents, {
    fields: [tournamentGroups.scoringEventId],
    references: [scoringEvents.id],
  }),
  members: many(tournamentGroupMembers),
}));

export const tournamentGroupMembersRelations = relations(tournamentGroupMembers, ({ one }) => ({
  group: one(tournamentGroups, {
    fields: [tournamentGroupMembers.tournamentGroupId],
    references: [tournamentGroups.id],
  }),
  participant: one(participants, {
    fields: [tournamentGroupMembers.participantId],
    references: [participants.id],
  }),
}));

export const participantEvSnapshotsRelations = relations(participantEvSnapshots, ({ one }) => ({
  participant: one(participants, {
    fields: [participantEvSnapshots.participantId],
    references: [participants.id],
  }),
  sportsSeason: one(sportsSeasons, {
    fields: [participantEvSnapshots.sportsSeasonId],
    references: [sportsSeasons.id],
  }),
}));

export const teamEvSnapshotsRelations = relations(teamEvSnapshots, ({ one }) => ({
  team: one(teams, {
    fields: [teamEvSnapshots.teamId],
    references: [teams.id],
  }),
  season: one(seasons, {
    fields: [teamEvSnapshots.seasonId],
    references: [seasons.id],
  }),
}));

// Regular season W/L standings for team-sport playoff_bracket seasons (NBA, NHL, etc.)
// Populated by the standings sync service; syncedAt = null means manually entered
export const regularSeasonStandings = pgTable("regular_season_standings", {
  id: uuid("id").primaryKey().defaultRandom(),
  participantId: uuid("participant_id")
    .notNull()
    .references(() => participants.id, { onDelete: "cascade" }),
  sportsSeasonId: uuid("sports_season_id")
    .notNull()
    .references(() => sportsSeasons.id, { onDelete: "cascade" }),
  wins: integer("wins").notNull().default(0),
  losses: integer("losses").notNull().default(0),
  otLosses: integer("ot_losses"),            // NHL overtime losses; null for NBA
  ties: integer("ties"),                      // future sports (e.g. soccer)
  winPct: decimal("win_pct", { precision: 5, scale: 4 }),
  gamesPlayed: integer("games_played").notNull().default(0),
  gamesBack: decimal("games_back", { precision: 5, scale: 1 }),
  conference: varchar("conference", { length: 100 }),
  division: varchar("division", { length: 100 }),
  conferenceRank: integer("conference_rank"),
  divisionRank: integer("division_rank"),
  leagueRank: integer("league_rank"),
  streak: varchar("streak", { length: 20 }),       // e.g. "W3", "L2"
  lastTen: varchar("last_ten", { length: 15 }),    // e.g. "7-2-1"
  homeRecord: varchar("home_record", { length: 15 }),
  awayRecord: varchar("away_record", { length: 15 }),
  externalTeamId: varchar("external_team_id", { length: 255 }),
  syncedAt: timestamp("synced_at"),                // null = manually entered
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
}, (table) => ({
  uniqueParticipantSeason: uniqueIndex("rss_participant_season_idx")
    .on(table.participantId, table.sportsSeasonId),
}));

export const regularSeasonStandingsRelations = relations(regularSeasonStandings, ({ one }) => ({
  participant: one(participants, {
    fields: [regularSeasonStandings.participantId],
    references: [participants.id],
  }),
  sportsSeason: one(sportsSeasons, {
    fields: [regularSeasonStandings.sportsSeasonId],
    references: [sportsSeasons.id],
  }),
}));

// Unmatched teams from a standings sync — awaiting admin resolution.
// Once the admin maps an external team to a participant, this record is deleted
// and the standing + participant.externalId are written.
export const pendingStandingsMappings = pgTable("pending_standings_mappings", {
  id: uuid("id").primaryKey().defaultRandom(),
  sportsSeasonId: uuid("sports_season_id")
    .notNull()
    .references(() => sportsSeasons.id, { onDelete: "cascade" }),
  externalTeamId: varchar("external_team_id", { length: 255 }).notNull(),
  teamName: varchar("team_name", { length: 255 }).notNull(),
  // Full standing data from the API, stored as JSON for use when resolving
  standingData: jsonb("standing_data").notNull(),
  createdAt: timestamp("created_at").defaultNow().notNull(),
}, (table) => ({
  uniqueSeasonExternalId: uniqueIndex("psm_season_external_id_idx")
    .on(table.sportsSeasonId, table.externalTeamId),
}));

export const pendingStandingsMappingsRelations = relations(pendingStandingsMappings, ({ one }) => ({
  sportsSeason: one(sportsSeasons, {
    fields: [pendingStandingsMappings.sportsSeasonId],
    references: [sportsSeasons.id],
  }),
}));

// ─── Participant Surface Elos ─────────────────────────────────────────────────
// Stores surface-specific Elo ratings for tennis (and future surface-based sports).
// One row per (participantId, sportsSeasonId); nullable per surface.

export const participantSurfaceElos = pgTable("participant_surface_elos", {
  id: uuid("id").primaryKey().defaultRandom(),
  participantId: uuid("participant_id")
    .notNull()
    .references(() => participants.id, { onDelete: "cascade" }),
  sportsSeasonId: uuid("sports_season_id")
    .notNull()
    .references(() => sportsSeasons.id, { onDelete: "cascade" }),
  worldRanking: integer("world_ranking"),
  eloHard: integer("elo_hard"),
  eloClay: integer("elo_clay"),
  eloGrass: integer("elo_grass"),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
}, (t) => ({
  uniqueParticipantSeason: uniqueIndex("participant_surface_elos_unique")
    .on(t.participantId, t.sportsSeasonId),
}));

export const participantSurfaceElosRelations = relations(participantSurfaceElos, ({ one }) => ({
  participant: one(participants, {
    fields: [participantSurfaceElos.participantId],
    references: [participants.id],
  }),
  sportsSeason: one(sportsSeasons, {
    fields: [participantSurfaceElos.sportsSeasonId],
    references: [sportsSeasons.id],
  }),
}));
