-- ============================================================================
-- OrbiQuant IA - Trading Platform
-- Schema: auth
-- File: tables/01-users.sql
-- Description: Core users table for authentication and user management
-- ============================================================================

CREATE TABLE auth.users (
  -- Primary Key
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),

  -- Authentication Credentials
  email CITEXT NOT NULL UNIQUE,
  email_verified BOOLEAN NOT NULL DEFAULT false,
  email_verified_at TIMESTAMPTZ,
  password_hash VARCHAR(255),

  -- User Status and Role
  status auth.user_status NOT NULL DEFAULT 'pending_verification',
  role auth.user_role NOT NULL DEFAULT 'user',

  -- Multi-Factor Authentication
  mfa_enabled BOOLEAN NOT NULL DEFAULT false,
  mfa_method auth.mfa_method NOT NULL DEFAULT 'none',
  mfa_secret VARCHAR(255),
  backup_codes JSONB DEFAULT '[]',

  -- Phone Information
  phone_number VARCHAR(20),
  phone_verified BOOLEAN NOT NULL DEFAULT false,
  phone_verified_at TIMESTAMPTZ,

  -- Security Settings
  last_login_at TIMESTAMPTZ,
  last_login_ip INET,
  failed_login_attempts INTEGER NOT NULL DEFAULT 0,
  locked_until TIMESTAMPTZ,

  -- Account Lifecycle
  suspended_at TIMESTAMPTZ,
  suspended_reason TEXT,
  deactivated_at TIMESTAMPTZ,

  -- Audit Fields
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  created_by_id UUID,
  updated_by_id UUID,

  -- Constraints
  CONSTRAINT valid_email CHECK (email ~* '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$'),
  -- NOTE: password_or_oauth constraint moved to 99-deferred-constraints.sql
  -- to resolve circular dependency with oauth_accounts
  CONSTRAINT failed_attempts_non_negative CHECK (failed_login_attempts >= 0),
  CONSTRAINT email_verified_at_consistency CHECK (
    (email_verified = true AND email_verified_at IS NOT NULL) OR
    (email_verified = false AND email_verified_at IS NULL)
  ),
  CONSTRAINT phone_verified_at_consistency CHECK (
    (phone_verified = true AND phone_verified_at IS NOT NULL) OR
    (phone_verified = false AND phone_verified_at IS NULL)
  ),
  CONSTRAINT mfa_secret_consistency CHECK (
    (mfa_enabled = true AND mfa_secret IS NOT NULL AND mfa_method != 'none') OR
    (mfa_enabled = false)
  )
);

-- Indexes for Performance
CREATE INDEX idx_users_email ON auth.users(email);
CREATE INDEX idx_users_status ON auth.users(status);
CREATE INDEX idx_users_role ON auth.users(role);
CREATE INDEX idx_users_last_login ON auth.users(last_login_at DESC);
CREATE INDEX idx_users_created_at ON auth.users(created_at DESC);
CREATE INDEX idx_users_email_verified ON auth.users(email_verified) WHERE email_verified = false;
CREATE INDEX idx_users_locked ON auth.users(locked_until) WHERE locked_until IS NOT NULL;
CREATE INDEX idx_users_phone ON auth.users(phone_number) WHERE phone_number IS NOT NULL;

-- Table Comments
COMMENT ON TABLE auth.users IS 'Core users table for authentication and user management';

-- Column Comments
COMMENT ON COLUMN auth.users.id IS 'Unique identifier for the user';
COMMENT ON COLUMN auth.users.email IS 'User email address (case-insensitive, unique)';
COMMENT ON COLUMN auth.users.email_verified IS 'Whether the email has been verified';
COMMENT ON COLUMN auth.users.email_verified_at IS 'Timestamp when email was verified';
COMMENT ON COLUMN auth.users.password_hash IS 'Bcrypt hashed password (null for OAuth-only users)';
COMMENT ON COLUMN auth.users.status IS 'Current status of the user account';
COMMENT ON COLUMN auth.users.role IS 'User role for role-based access control';
COMMENT ON COLUMN auth.users.mfa_enabled IS 'Whether multi-factor authentication is enabled';
COMMENT ON COLUMN auth.users.mfa_method IS 'MFA method used (totp, sms, email)';
COMMENT ON COLUMN auth.users.mfa_secret IS 'Secret key for TOTP MFA';
COMMENT ON COLUMN auth.users.phone_number IS 'User phone number for SMS verification';
COMMENT ON COLUMN auth.users.phone_verified IS 'Whether the phone number has been verified';
COMMENT ON COLUMN auth.users.phone_verified_at IS 'Timestamp when phone was verified';
COMMENT ON COLUMN auth.users.last_login_at IS 'Timestamp of last successful login';
COMMENT ON COLUMN auth.users.last_login_ip IS 'IP address of last successful login';
COMMENT ON COLUMN auth.users.failed_login_attempts IS 'Counter for failed login attempts';
COMMENT ON COLUMN auth.users.locked_until IS 'Account locked until this timestamp (null if not locked)';
COMMENT ON COLUMN auth.users.suspended_at IS 'Timestamp when account was suspended';
COMMENT ON COLUMN auth.users.suspended_reason IS 'Reason for account suspension';
COMMENT ON COLUMN auth.users.deactivated_at IS 'Timestamp when account was deactivated';
COMMENT ON COLUMN auth.users.created_at IS 'Timestamp when user was created';
COMMENT ON COLUMN auth.users.updated_at IS 'Timestamp when user was last updated';
COMMENT ON COLUMN auth.users.created_by_id IS 'ID of user who created this record';
COMMENT ON COLUMN auth.users.updated_by_id IS 'ID of user who last updated this record';
