-- AI Code Battle D1 Schema
-- Complete schema with all tables from the implementation plan

-- ============================================
-- Core Tables (Phase 4)
-- ============================================

-- Bots table: stores registered bots
CREATE TABLE IF NOT EXISTS bots (
  id TEXT PRIMARY KEY,
  name TEXT NOT NULL UNIQUE,
  owner_id TEXT NOT NULL,
  endpoint_url TEXT NOT NULL,
  api_key_hash TEXT NOT NULL,
  rating REAL NOT NULL DEFAULT 1500.0,
  rating_deviation REAL NOT NULL DEFAULT 350.0,
  rating_volatility REAL NOT NULL DEFAULT 0.06,
  evolved INTEGER NOT NULL DEFAULT 0,
  island TEXT,
  generation INTEGER,
  parent_ids TEXT,
  description TEXT,
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
  updated_at TEXT NOT NULL DEFAULT (datetime('now')),
  last_health_check TEXT,
  health_status TEXT DEFAULT 'unknown',
  matches_played INTEGER NOT NULL DEFAULT 0,
  matches_won INTEGER NOT NULL DEFAULT 0
);

CREATE INDEX IF NOT EXISTS idx_bots_owner ON bots(owner_id);
CREATE INDEX IF NOT EXISTS idx_bots_rating ON bots(rating DESC);
CREATE INDEX IF NOT EXISTS idx_bots_evolved ON bots(evolved);

-- Matches table: stores match metadata
CREATE TABLE IF NOT EXISTS matches (
  id TEXT PRIMARY KEY,
  status TEXT NOT NULL DEFAULT 'pending',
  winner_id TEXT,
  turns INTEGER,
  end_reason TEXT,
  map_id TEXT NOT NULL,
  scores_json TEXT,
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
  started_at TEXT,
  completed_at TEXT
);

CREATE INDEX IF NOT EXISTS idx_matches_status ON matches(status);
CREATE INDEX IF NOT EXISTS idx_matches_created ON matches(created_at DESC);
CREATE INDEX IF NOT EXISTS idx_matches_map ON matches(map_id);

-- Match participants: links bots to matches
CREATE TABLE IF NOT EXISTS match_participants (
  id TEXT PRIMARY KEY,
  match_id TEXT NOT NULL,
  bot_id TEXT NOT NULL,
  player_index INTEGER NOT NULL,
  score INTEGER NOT NULL DEFAULT 0,
  status TEXT,
  rating_before REAL NOT NULL,
  rating_after REAL,
  rating_deviation_before REAL NOT NULL,
  rating_deviation_after REAL,
  FOREIGN KEY (match_id) REFERENCES matches(id) ON DELETE CASCADE,
  FOREIGN KEY (bot_id) REFERENCES bots(id) ON DELETE CASCADE,
  UNIQUE(match_id, bot_id),
  UNIQUE(match_id, player_index)
);

CREATE INDEX IF NOT EXISTS idx_match_participants_match ON match_participants(match_id);
CREATE INDEX IF NOT EXISTS idx_match_participants_bot ON match_participants(bot_id);

-- Jobs table: match execution jobs for workers
CREATE TABLE IF NOT EXISTS jobs (
  id TEXT PRIMARY KEY,
  match_id TEXT NOT NULL,
  status TEXT NOT NULL DEFAULT 'pending',
  worker_id TEXT,
  claimed_at TEXT,
  heartbeat_at TEXT,
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
  completed_at TEXT,
  error_message TEXT,
  FOREIGN KEY (match_id) REFERENCES matches(id) ON DELETE CASCADE
);

CREATE INDEX IF NOT EXISTS idx_jobs_status ON jobs(status);
CREATE INDEX IF NOT EXISTS idx_jobs_worker ON jobs(worker_id);
CREATE INDEX IF NOT EXISTS idx_jobs_heartbeat ON jobs(heartbeat_at);

-- Rating history: tracks rating changes over time
CREATE TABLE IF NOT EXISTS rating_history (
  id TEXT PRIMARY KEY,
  bot_id TEXT NOT NULL,
  match_id TEXT NOT NULL,
  rating_before REAL NOT NULL,
  rating_after REAL NOT NULL,
  rating_deviation REAL NOT NULL,
  recorded_at TEXT NOT NULL DEFAULT (datetime('now')),
  FOREIGN KEY (bot_id) REFERENCES bots(id) ON DELETE CASCADE,
  FOREIGN KEY (match_id) REFERENCES matches(id) ON DELETE CASCADE
);

CREATE INDEX IF NOT EXISTS idx_rating_history_bot ON rating_history(bot_id);
CREATE INDEX IF NOT EXISTS idx_rating_history_time ON rating_history(recorded_at DESC);

-- Maps table: stores generated maps
CREATE TABLE IF NOT EXISTS maps (
  id TEXT PRIMARY KEY,
  width INTEGER NOT NULL,
  height INTEGER NOT NULL,
  player_count INTEGER NOT NULL DEFAULT 2,
  walls TEXT NOT NULL,
  spawns TEXT NOT NULL,
  cores TEXT NOT NULL,
  energy_nodes TEXT NOT NULL,
  wall_density REAL NOT NULL DEFAULT 0.15,
  status TEXT NOT NULL DEFAULT 'active',
  engagement_score REAL DEFAULT 0,
  created_at TEXT NOT NULL DEFAULT (datetime('now'))
);

CREATE INDEX IF NOT EXISTS idx_maps_status ON maps(status);
CREATE INDEX IF NOT EXISTS idx_maps_player_count ON maps(player_count);
CREATE INDEX IF NOT EXISTS idx_maps_engagement ON maps(engagement_score DESC);

-- Bot secrets: stores API keys for bots (separate for security)
CREATE TABLE IF NOT EXISTS bot_secrets (
  bot_id TEXT PRIMARY KEY,
  api_key_hash TEXT NOT NULL,
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
  FOREIGN KEY (bot_id) REFERENCES bots(id) ON DELETE CASCADE
);

-- ============================================
-- Prediction System (Section 13.5)
-- ============================================

-- Predictions: visitor predictions on match outcomes
CREATE TABLE IF NOT EXISTS predictions (
  id TEXT PRIMARY KEY,
  match_id TEXT NOT NULL,
  predictor_id TEXT NOT NULL,
  predictor_name TEXT,
  predicted_bot_id TEXT NOT NULL,
  correct INTEGER,
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
  FOREIGN KEY (match_id) REFERENCES matches(id) ON DELETE CASCADE,
  FOREIGN KEY (predicted_bot_id) REFERENCES bots(id) ON DELETE CASCADE
);

CREATE INDEX IF NOT EXISTS idx_predictions_match ON predictions(match_id);
CREATE INDEX IF NOT EXISTS idx_predictions_predictor ON predictions(predictor_id);

-- Predictor stats: aggregate prediction accuracy
CREATE TABLE IF NOT EXISTS predictor_stats (
  predictor_id TEXT PRIMARY KEY,
  predictor_name TEXT,
  correct INTEGER NOT NULL DEFAULT 0,
  incorrect INTEGER NOT NULL DEFAULT 0,
  streak INTEGER NOT NULL DEFAULT 0,
  best_streak INTEGER NOT NULL DEFAULT 0,
  rating REAL NOT NULL DEFAULT 1000.0
);

CREATE INDEX IF NOT EXISTS idx_predictor_stats_rating ON predictor_stats(rating DESC);

-- ============================================
-- Map Voting (Section 13.6)
-- ============================================

-- Map votes: community voting on map quality
CREATE TABLE IF NOT EXISTS map_votes (
  id TEXT PRIMARY KEY,
  map_id TEXT NOT NULL,
  voter_id TEXT NOT NULL,
  vote INTEGER NOT NULL,
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
  FOREIGN KEY (map_id) REFERENCES maps(id) ON DELETE CASCADE,
  UNIQUE(map_id, voter_id)
);

CREATE INDEX IF NOT EXISTS idx_map_votes_map ON map_votes(map_id);

-- ============================================
-- Replay Feedback (Section 13.6)
-- ============================================

-- Replay feedback: community annotations on replays
CREATE TABLE IF NOT EXISTS replay_feedback (
  id TEXT PRIMARY KEY,
  match_id TEXT NOT NULL,
  turn INTEGER NOT NULL,
  type TEXT NOT NULL,
  body TEXT NOT NULL,
  author TEXT NOT NULL,
  upvotes INTEGER NOT NULL DEFAULT 0,
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
  FOREIGN KEY (match_id) REFERENCES matches(id) ON DELETE CASCADE
);

CREATE INDEX IF NOT EXISTS idx_feedback_match ON replay_feedback(match_id, turn);
CREATE INDEX IF NOT EXISTS idx_feedback_type ON replay_feedback(type);
CREATE INDEX IF NOT EXISTS idx_feedback_upvotes ON replay_feedback(upvotes DESC);

-- ============================================
-- Multi-Game Series (Section 14.7)
-- ============================================

-- Series: best-of-N match series between two bots
CREATE TABLE IF NOT EXISTS series (
  id TEXT PRIMARY KEY,
  bot_a_id TEXT NOT NULL,
  bot_b_id TEXT NOT NULL,
  format INTEGER NOT NULL,
  status TEXT NOT NULL DEFAULT 'pending',
  a_wins INTEGER NOT NULL DEFAULT 0,
  b_wins INTEGER NOT NULL DEFAULT 0,
  season_id TEXT,
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
  completed_at TEXT,
  FOREIGN KEY (bot_a_id) REFERENCES bots(id) ON DELETE CASCADE,
  FOREIGN KEY (bot_b_id) REFERENCES bots(id) ON DELETE CASCADE
);

CREATE INDEX IF NOT EXISTS idx_series_status ON series(status);
CREATE INDEX IF NOT EXISTS idx_series_bots ON series(bot_a_id, bot_b_id);
CREATE INDEX IF NOT EXISTS idx_series_season ON series(season_id);

-- Series games: individual games within a series
CREATE TABLE IF NOT EXISTS series_games (
  series_id TEXT NOT NULL,
  game_number INTEGER NOT NULL,
  match_id TEXT,
  map_id TEXT NOT NULL,
  winner INTEGER,
  PRIMARY KEY (series_id, game_number),
  FOREIGN KEY (series_id) REFERENCES series(id) ON DELETE CASCADE,
  FOREIGN KEY (match_id) REFERENCES matches(id) ON DELETE SET NULL
);

CREATE INDEX IF NOT EXISTS idx_series_games_match ON series_games(match_id);

-- ============================================
-- Seasonal Rotations (Section 14.9)
-- ============================================

-- Seasons: seasonal leaderboards with rule variations
CREATE TABLE IF NOT EXISTS seasons (
  id TEXT PRIMARY KEY,
  name TEXT NOT NULL,
  theme TEXT NOT NULL,
  rules_version INTEGER NOT NULL DEFAULT 1,
  started_at TEXT NOT NULL,
  ended_at TEXT,
  champion_id TEXT,
  status TEXT NOT NULL DEFAULT 'active',
  FOREIGN KEY (champion_id) REFERENCES bots(id) ON DELETE SET NULL
);

CREATE INDEX IF NOT EXISTS idx_seasons_status ON seasons(status);
CREATE INDEX IF NOT EXISTS idx_seasons_dates ON seasons(started_at, ended_at);
