import { createPool, waitForDatabase } from './db.mjs'

const pool = createPool()

try {
  await waitForDatabase(pool)
  await pool.query('begin')
  await pool.query(`
    create extension if not exists pgcrypto;

    create table if not exists app_users (
      id uuid primary key default gen_random_uuid(),
      auth_issuer text not null,
      auth_subject text not null,
      username text,
      password_hash text,
      password_salt text,
      display_name text not null default 'Healer',
      created_at timestamptz not null default now(),
      updated_at timestamptz not null default now(),
      unique (auth_issuer, auth_subject)
    );

    alter table app_users add column if not exists username text;
    alter table app_users add column if not exists password_hash text;
    alter table app_users add column if not exists password_salt text;

    create unique index if not exists app_users_username_lower_idx
      on app_users (lower(username))
      where username is not null;

    create table if not exists sessions (
      id uuid primary key default gen_random_uuid(),
      user_id uuid not null references app_users(id) on delete cascade,
      token_hash text not null unique,
      expires_at timestamptz not null,
      created_ip text not null,
      created_at timestamptz not null default now()
    );

    create table if not exists save_slots (
      id uuid primary key default gen_random_uuid(),
      user_id uuid not null references app_users(id) on delete cascade,
      slot_key text not null default 'default',
      save_json jsonb not null,
      save_version integer not null default 1,
      client_updated_at timestamptz,
      created_at timestamptz not null default now(),
      updated_at timestamptz not null default now(),
      unique (user_id, slot_key)
    );

    create table if not exists action_mechanic_configs (
      id uuid primary key default gen_random_uuid(),
      user_id uuid references app_users(id) on delete cascade,
      config_key text not null default 'default',
      config_json jsonb not null,
      created_at timestamptz not null default now(),
      updated_at timestamptz not null default now(),
      unique (user_id, config_key)
    );

    create table if not exists pvp_queue (
      id uuid primary key default gen_random_uuid(),
      user_id uuid not null references app_users(id) on delete cascade,
      mode text not null default 'action-healer',
      rating integer not null default 1000,
      status text not null default 'queued',
      queued_at timestamptz not null default now(),
      updated_at timestamptz not null default now(),
      unique (user_id, mode, status)
    );

    create table if not exists pvp_matches (
      id uuid primary key default gen_random_uuid(),
      mode text not null default 'action-healer',
      status text not null default 'pending',
      player_one_id uuid not null references app_users(id) on delete cascade,
      player_two_id uuid references app_users(id) on delete cascade,
      match_state jsonb not null default '{}'::jsonb,
      created_at timestamptz not null default now(),
      updated_at timestamptz not null default now(),
      completed_at timestamptz
    );

    create index if not exists save_slots_user_id_idx on save_slots(user_id);
    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 index if not exists pvp_queue_mode_status_idx on pvp_queue(mode, status, queued_at);
    create index if not exists pvp_matches_player_one_idx on pvp_matches(player_one_id);
    create index if not exists pvp_matches_player_two_idx on pvp_matches(player_two_id);
  `)
  await pool.query('commit')
  console.log('Database initialized.')
} catch (error) {
  await pool.query('rollback').catch(() => {})
  console.error(error)
  process.exitCode = 1
} finally {
  await pool.end()
}
