CREATE EXTENSION IF NOT EXISTS timescaledb;
CREATE EXTENSION IF NOT EXISTS btree_gist;

CREATE TABLE IF NOT EXISTS venues (
  id TEXT PRIMARY KEY,
  name TEXT NOT NULL,
  city TEXT NOT NULL,
  country TEXT NOT NULL,
  altitude_meters INTEGER,
  timezone TEXT NOT NULL
);

CREATE TABLE IF NOT EXISTS teams (
  id TEXT PRIMARY KEY,
  name TEXT NOT NULL UNIQUE,
  fifa_rank INTEGER,
  current_elo_rating DOUBLE PRECISION,
  group_name TEXT
);

CREATE TABLE IF NOT EXISTS bookmakers (
  id TEXT PRIMARY KEY,
  name TEXT NOT NULL UNIQUE
);

CREATE TABLE IF NOT EXISTS matches (
  id TEXT PRIMARY KEY,
  home_team_id TEXT NOT NULL REFERENCES teams (id),
  away_team_id TEXT NOT NULL REFERENCES teams (id),
  venue_id TEXT NOT NULL REFERENCES venues (id),
  match_time_utc TIMESTAMPTZ NOT NULL,
  status TEXT NOT NULL DEFAULT 'pre-match',
  home_xg DOUBLE PRECISION,
  away_xg DOUBLE PRECISION,
  home_score INTEGER,
  away_score INTEGER,
  result_synced_at TIMESTAMPTZ
);

CREATE TABLE IF NOT EXISTS odds_history (
  id BIGSERIAL,
  match_id TEXT NOT NULL REFERENCES matches (id),
  bookmaker_id TEXT NOT NULL REFERENCES bookmakers (id),
  market_type TEXT NOT NULL,
  selection TEXT NOT NULL,
  market_line DOUBLE PRECISION,
  handicap DOUBLE PRECISION,
  decimal_odds DOUBLE PRECISION NOT NULL,
  implied_probability DOUBLE PRECISION NOT NULL,
  source_market_key TEXT,
  source_outcome_name TEXT,
  recorded_at TIMESTAMPTZ NOT NULL,
  PRIMARY KEY (id, recorded_at)
);

CREATE TABLE IF NOT EXISTS smart_money_flow (
  id BIGSERIAL PRIMARY KEY,
  match_id TEXT NOT NULL REFERENCES matches (id),
  market_type TEXT NOT NULL,
  selection TEXT NOT NULL,
  ticket_pct DOUBLE PRECISION NOT NULL,
  handle_pct DOUBLE PRECISION NOT NULL,
  sharp_indicator BOOLEAN NOT NULL,
  recorded_at TIMESTAMPTZ NOT NULL
);

CREATE INDEX IF NOT EXISTS idx_matches_time_status ON matches (match_time_utc, status);
CREATE INDEX IF NOT EXISTS idx_odds_match_market_recorded_at
  ON odds_history (match_id, market_type, recorded_at DESC);
CREATE INDEX IF NOT EXISTS idx_odds_match_market_line_recorded_at
  ON odds_history (match_id, market_type, selection, market_line, handicap, recorded_at DESC);
CREATE INDEX IF NOT EXISTS idx_money_flow_match_recorded_at
  ON smart_money_flow (match_id, market_type, recorded_at DESC);

CREATE TABLE IF NOT EXISTS value_bet_recommendations (
  id TEXT PRIMARY KEY,
  match_id TEXT NOT NULL REFERENCES matches (id),
  market_type TEXT NOT NULL,
  selection TEXT NOT NULL,
  stake DOUBLE PRECISION NOT NULL,
  recommended_odds DOUBLE PRECISION NOT NULL,
  closing_odds DOUBLE PRECISION,
  is_win BOOLEAN NOT NULL DEFAULT FALSE,
  settled_at TIMESTAMPTZ NOT NULL,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  clv_ratio DOUBLE PRECISION,
  pnl DOUBLE PRECISION NOT NULL DEFAULT 0,
  note TEXT
);

CREATE INDEX IF NOT EXISTS idx_value_bet_recommendations_match_time
  ON value_bet_recommendations (match_id, settled_at DESC);

SELECT create_hypertable(
  'odds_history',
  'recorded_at',
  chunk_time_interval => INTERVAL '1 hour',
  if_not_exists => TRUE
);

CREATE INDEX IF NOT EXISTS idx_odds_history_time_gist
  ON odds_history USING GIST (recorded_at);

-- Stage 33: Affiliate Marketing
CREATE TABLE IF NOT EXISTS affiliate_bookmakers (
  id TEXT PRIMARY KEY,
  name TEXT NOT NULL UNIQUE,
  tracking_url TEXT NOT NULL,
  commission_rate DOUBLE PRECISION NOT NULL DEFAULT 0.0
);

CREATE TABLE IF NOT EXISTS affiliate_clicks (
  id BIGSERIAL,
  bookmaker_id TEXT NOT NULL REFERENCES affiliate_bookmakers (id),
  user_ip_hash TEXT NOT NULL,
  user_agent TEXT,
  referrer TEXT,
  timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  converted BOOLEAN NOT NULL DEFAULT FALSE,
  PRIMARY KEY (id, timestamp)
);

CREATE INDEX IF NOT EXISTS idx_affiliate_clicks_timestamp
  ON affiliate_clicks (timestamp DESC);

SELECT create_hypertable(
  'affiliate_clicks',
  'timestamp',
  chunk_time_interval => INTERVAL '1 day',
  if_not_exists => TRUE
);

-- Note: TimescaleDB continuous aggregates require a bit more setup in modern versions.
-- A simple materialized view for daily conversion rates:
CREATE MATERIALIZED VIEW IF NOT EXISTS affiliate_daily_conversions
WITH (timescaledb.continuous) AS
SELECT
  time_bucket('1 day', timestamp) AS bucket,
  bookmaker_id,
  COUNT(*) AS total_clicks,
  COUNT(*) FILTER (WHERE converted = TRUE) AS total_conversions
FROM affiliate_clicks
GROUP BY bucket, bookmaker_id
WITH NO DATA;

-- Stage 35: Social Trading (Copy Bets & Leaderboard)
CREATE TABLE IF NOT EXISTS user_profiles (
  id TEXT PRIMARY KEY,
  username TEXT NOT NULL UNIQUE,
  clv_score DOUBLE PRECISION NOT NULL DEFAULT 0.0,
  roi_30d DOUBLE PRECISION NOT NULL DEFAULT 0.0,
  sharp_rating INTEGER NOT NULL DEFAULT 0
);

CREATE TABLE IF NOT EXISTS copy_bets (
  id BIGSERIAL PRIMARY KEY,
  follower_id TEXT NOT NULL REFERENCES user_profiles(id),
  leader_id TEXT NOT NULL REFERENCES user_profiles(id),
  recommendation_id TEXT NOT NULL REFERENCES value_bet_recommendations(id),
  follower_stake DOUBLE PRECISION NOT NULL,
  copied_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_copy_bets_leader_time
  ON copy_bets (leader_id, copied_at DESC);
