CREATE DATABASE IF NOT EXISTS hy_user DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

USE hy_user;

CREATE TABLE IF NOT EXISTS users (
  user_id BIGINT NOT NULL PRIMARY KEY,
  default_display_user_id VARCHAR(32) NOT NULL,
  current_display_user_id VARCHAR(32) NOT NULL,
  current_display_user_id_kind VARCHAR(32) NOT NULL,
  current_display_user_id_expires_at_ms BIGINT NULL,
  status VARCHAR(32) NOT NULL,
  created_at_ms BIGINT NOT NULL,
  updated_at_ms BIGINT NOT NULL,
  UNIQUE KEY uk_users_default_display_user_id (default_display_user_id),
  UNIQUE KEY uk_users_current_display_user_id (current_display_user_id),
  KEY idx_users_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS user_display_user_ids (
  id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  display_user_id VARCHAR(32) NOT NULL,
  user_id BIGINT NOT NULL,
  display_user_id_kind VARCHAR(32) NOT NULL,
  status VARCHAR(32) NOT NULL,
  assigned_at_ms BIGINT NOT NULL,
  activated_at_ms BIGINT NULL,
  expires_at_ms BIGINT NULL,
  released_at_ms BIGINT NULL,
  release_reason VARCHAR(64) NULL,
  created_at_ms BIGINT NOT NULL,
  updated_at_ms BIGINT NOT NULL,
  live_display_user_id VARCHAR(32)
    GENERATED ALWAYS AS (
      CASE
        WHEN status IN ('active', 'held', 'reserved', 'blocked') THEN display_user_id
        ELSE NULL
      END
    ) STORED,
  active_user_id BIGINT
    GENERATED ALWAYS AS (
      CASE WHEN status = 'active' THEN user_id ELSE NULL END
    ) STORED,
  UNIQUE KEY uk_user_display_user_ids_live (live_display_user_id),
  UNIQUE KEY uk_user_display_user_ids_active_user (active_user_id),
  KEY idx_user_display_user_ids_user_id (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS pretty_display_user_id_leases (
  lease_id VARCHAR(64) NOT NULL PRIMARY KEY,
  display_user_id VARCHAR(32) NOT NULL,
  user_id BIGINT NOT NULL,
  status VARCHAR(32) NOT NULL,
  starts_at_ms BIGINT NOT NULL,
  expires_at_ms BIGINT NOT NULL,
  payment_receipt_id VARCHAR(64) NULL,
  source VARCHAR(32) NOT NULL,
  created_at_ms BIGINT NOT NULL,
  updated_at_ms BIGINT NOT NULL,
  active_display_user_id VARCHAR(32)
    GENERATED ALWAYS AS (
      CASE WHEN status = 'active' THEN display_user_id ELSE NULL END
    ) STORED,
  active_user_id BIGINT
    GENERATED ALWAYS AS (
      CASE WHEN status = 'active' THEN user_id ELSE NULL END
    ) STORED,
  UNIQUE KEY uk_pretty_display_user_id_active (active_display_user_id),
  UNIQUE KEY uk_pretty_display_user_id_active_user (active_user_id),
  KEY idx_pretty_display_user_id_leases_user (user_id, status),
  KEY idx_pretty_display_user_id_leases_expire (status, expires_at_ms)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS display_user_id_change_logs (
  id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  user_id BIGINT NOT NULL,
  old_display_user_id VARCHAR(32) NOT NULL,
  new_display_user_id VARCHAR(32) NOT NULL,
  old_display_user_id_kind VARCHAR(32) NOT NULL,
  new_display_user_id_kind VARCHAR(32) NOT NULL,
  change_type VARCHAR(32) NOT NULL,
  lease_id VARCHAR(64) NULL,
  reason VARCHAR(64) NOT NULL,
  operator_user_id BIGINT NULL,
  request_id VARCHAR(96) NOT NULL,
  created_at_ms BIGINT NOT NULL,
  KEY idx_display_user_id_change_logs_user_id (user_id),
  KEY idx_display_user_id_change_logs_request_id (request_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS password_accounts (
  user_id BIGINT NOT NULL,
  password_hash VARCHAR(255) NOT NULL,
  hash_alg VARCHAR(32) NOT NULL,
  created_at_ms BIGINT NOT NULL,
  updated_at_ms BIGINT NOT NULL,
  PRIMARY KEY (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS third_party_identities (
  id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  user_id BIGINT NOT NULL,
  provider VARCHAR(64) NOT NULL,
  provider_subject VARCHAR(191) NOT NULL,
  provider_union_id VARCHAR(191) NULL,
  created_at_ms BIGINT NOT NULL,
  updated_at_ms BIGINT NOT NULL,
  UNIQUE KEY uk_third_party_provider_subject (provider, provider_subject),
  KEY idx_third_party_user_id (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS auth_sessions (
  session_id VARCHAR(96) NOT NULL PRIMARY KEY,
  user_id BIGINT NOT NULL,
  refresh_token_hash VARCHAR(128) NOT NULL,
  device_id VARCHAR(128) NOT NULL,
  expires_at_ms BIGINT NOT NULL,
  revoked_at_ms BIGINT NULL,
  created_at_ms BIGINT NOT NULL,
  updated_at_ms BIGINT NOT NULL,
  UNIQUE KEY uk_auth_sessions_refresh_token_hash (refresh_token_hash),
  KEY idx_auth_sessions_user_id (user_id),
  KEY idx_auth_sessions_expires_at (expires_at_ms)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS login_audit (
  id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  request_id VARCHAR(96) NOT NULL,
  user_id BIGINT NULL,
  login_type VARCHAR(32) NOT NULL,
  provider VARCHAR(64) NULL,
  result VARCHAR(32) NOT NULL,
  failure_code VARCHAR(64) NULL,
  client_ip VARCHAR(64) NULL,
  user_agent VARCHAR(512) NULL,
  created_at_ms BIGINT NOT NULL,
  KEY idx_login_audit_user_id (user_id),
  KEY idx_login_audit_request_id (request_id),
  KEY idx_login_audit_created_at (created_at_ms)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
