-- Migration 002: Gamification — Xu system, XP, streak, leaderboard
-- Run in Supabase Dashboard → SQL Editor (after 001_user_progress.sql)

-- ============================================================
-- User gamification state (one row per user)
-- ============================================================
CREATE TABLE IF NOT EXISTS user_gamification (
  user_id        UUID PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,
  xp             INT NOT NULL DEFAULT 0,
  level          TEXT NOT NULL DEFAULT 'beginner'
                   CHECK (level IN ('beginner', 'bronze', 'silver', 'gold', 'master')),
  streak         INT NOT NULL DEFAULT 0,
  longest_streak INT NOT NULL DEFAULT 0,
  last_active    DATE,
  xu             INT NOT NULL DEFAULT 50,   -- welcome bonus
  freeze_count   INT NOT NULL DEFAULT 0,
  created_at     TIMESTAMPTZ DEFAULT now()
);

-- ============================================================
-- Xu transaction log (immutable audit trail)
-- ============================================================
CREATE TABLE IF NOT EXISTS xu_transactions (
  id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id     UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  type        TEXT NOT NULL
                CHECK (type IN (
                  'earn_welcome', 'earn_daily', 'earn_streak', 'earn_ads',
                  'spend_freeze', 'spend_writing', 'spend_test'
                )),
  amount      INT NOT NULL,       -- positive = earn, negative = spend
  balance     INT NOT NULL,       -- xu balance after this transaction
  description TEXT,
  created_at  TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX IF NOT EXISTS idx_xu_transactions_user_date
  ON xu_transactions(user_id, created_at DESC);

-- ============================================================
-- Weekly leaderboard (reset every week)
-- ============================================================
CREATE TABLE IF NOT EXISTS weekly_leaderboard (
  id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id     UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  week_start  DATE NOT NULL,
  xp_earned   INT NOT NULL DEFAULT 0,
  rank        INT,
  UNIQUE (user_id, week_start)
);

CREATE INDEX IF NOT EXISTS idx_leaderboard_week_xp
  ON weekly_leaderboard(week_start, xp_earned DESC);

-- ============================================================
-- Row Level Security
-- ============================================================

-- user_gamification
ALTER TABLE user_gamification ENABLE ROW LEVEL SECURITY;

CREATE POLICY "Users can read own gamification"
  ON user_gamification FOR SELECT
  USING (auth.uid() = user_id);

CREATE POLICY "Users can insert own gamification"
  ON user_gamification FOR INSERT
  WITH CHECK (auth.uid() = user_id);

CREATE POLICY "Users can update own gamification"
  ON user_gamification FOR UPDATE
  USING (auth.uid() = user_id);

-- xu_transactions (immutable — no UPDATE/DELETE)
ALTER TABLE xu_transactions ENABLE ROW LEVEL SECURITY;

CREATE POLICY "Users can read own xu transactions"
  ON xu_transactions FOR SELECT
  USING (auth.uid() = user_id);

CREATE POLICY "Users can insert own xu transactions"
  ON xu_transactions FOR INSERT
  WITH CHECK (auth.uid() = user_id);

-- weekly_leaderboard (public read, own write)
ALTER TABLE weekly_leaderboard ENABLE ROW LEVEL SECURITY;

CREATE POLICY "Anyone can read leaderboard"
  ON weekly_leaderboard FOR SELECT
  USING (true);

CREATE POLICY "Users can insert own leaderboard"
  ON weekly_leaderboard FOR INSERT
  WITH CHECK (auth.uid() = user_id);

CREATE POLICY "Users can update own leaderboard"
  ON weekly_leaderboard FOR UPDATE
  USING (auth.uid() = user_id);

-- ============================================================
-- Trigger: auto-create gamification row on new user signup
-- ============================================================
CREATE OR REPLACE FUNCTION handle_new_user_gamification()
RETURNS TRIGGER AS $$
BEGIN
  INSERT INTO user_gamification (user_id, xu)
  VALUES (NEW.id, 50);

  INSERT INTO xu_transactions (user_id, type, amount, balance, description)
  VALUES (NEW.id, 'earn_welcome', 50, 50, 'Welcome bonus');

  RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

CREATE TRIGGER on_auth_user_created_gamification
  AFTER INSERT ON auth.users
  FOR EACH ROW
  EXECUTE FUNCTION handle_new_user_gamification();
