PRAGMA foreign_keys = ON;
PRAGMA journal_mode = WAL;

CREATE TABLE IF NOT EXISTS accounts (
  id INTEGER PRIMARY KEY,
  username TEXT NOT NULL,
  canonical_username TEXT NOT NULL UNIQUE,
  password_hash TEXT NOT NULL,
  password_salt TEXT NOT NULL,
  created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE IF NOT EXISTS sessions (
  id INTEGER PRIMARY KEY,
  account_id INTEGER NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
  token_hash TEXT NOT NULL UNIQUE,
  expires_at TEXT NOT NULL,
  created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX IF NOT EXISTS sessions_token_hash_idx ON sessions(token_hash);
CREATE INDEX IF NOT EXISTS sessions_expires_at_idx ON sessions(expires_at);

CREATE TABLE IF NOT EXISTS hunter_saves (
  account_id INTEGER NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
  slot_id INTEGER NOT NULL CHECK (slot_id BETWEEN 1 AND 3),
  hunter_name TEXT NOT NULL,
  save_json TEXT NOT NULL,
  updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (account_id, slot_id)
);

CREATE TABLE IF NOT EXISTS boss_kill_records (
  account_id INTEGER NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
  slot_id INTEGER NOT NULL CHECK (slot_id BETWEEN 1 AND 3),
  boss_id TEXT NOT NULL,
  kills INTEGER NOT NULL DEFAULT 0 CHECK (kills >= 0),
  updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (account_id, slot_id, boss_id),
  FOREIGN KEY (account_id, slot_id) REFERENCES hunter_saves(account_id, slot_id) ON DELETE CASCADE
);

CREATE INDEX IF NOT EXISTS boss_kill_rank_idx
  ON boss_kill_records (boss_id, kills DESC, updated_at ASC);

CREATE TABLE IF NOT EXISTS roguelike_records (
  account_id INTEGER NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
  slot_id INTEGER NOT NULL CHECK (slot_id BETWEEN 1 AND 3),
  highest_round INTEGER NOT NULL DEFAULT 0 CHECK (highest_round >= 0),
  updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (account_id, slot_id),
  FOREIGN KEY (account_id, slot_id) REFERENCES hunter_saves(account_id, slot_id) ON DELETE CASCADE
);

CREATE INDEX IF NOT EXISTS roguelike_rank_idx
  ON roguelike_records (highest_round DESC, updated_at ASC);

CREATE TABLE IF NOT EXISTS rogue_trials_endless_records (
  account_id INTEGER NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
  slot_id INTEGER NOT NULL CHECK (slot_id BETWEEN 1 AND 3),
  highest_boss_kills INTEGER NOT NULL DEFAULT 0 CHECK (highest_boss_kills >= 0),
  updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (account_id, slot_id),
  FOREIGN KEY (account_id, slot_id) REFERENCES hunter_saves(account_id, slot_id) ON DELETE CASCADE
);

CREATE INDEX IF NOT EXISTS rogue_trials_endless_rank_idx
  ON rogue_trials_endless_records (highest_boss_kills DESC, updated_at ASC);
