-- ============================================
-- TEMPLATE-SAAS: Users Table
-- Schema: users
-- Version: 1.0.0
-- ============================================

CREATE TABLE users.users (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES tenants.tenants(id) ON DELETE CASCADE,

    -- Authentication
    email VARCHAR(255) NOT NULL,
    password_hash VARCHAR(255),  -- NULL for OAuth-only users
    email_verified BOOLEAN DEFAULT FALSE,
    email_verified_at TIMESTAMPTZ,

    -- Profile
    first_name VARCHAR(100),
    last_name VARCHAR(100),
    display_name VARCHAR(200),
    avatar_url VARCHAR(500),
    phone VARCHAR(50),
    phone_verified BOOLEAN DEFAULT FALSE,

    -- Status
    status users.user_status DEFAULT 'pending' NOT NULL,
    is_owner BOOLEAN DEFAULT FALSE,  -- Tenant owner

    -- Security
    mfa_enabled BOOLEAN DEFAULT FALSE,
    mfa_secret VARCHAR(255),
    password_changed_at TIMESTAMPTZ,
    failed_login_attempts INT DEFAULT 0,
    locked_until TIMESTAMPTZ,

    -- Preferences (JSONB)
    preferences JSONB DEFAULT '{}'::jsonb,
    -- Example:
    -- {
    --   "theme": "dark",
    --   "language": "es",
    --   "notifications": { "email": true, "push": true }
    -- }

    -- Metadata
    metadata JSONB DEFAULT '{}'::jsonb,

    -- Activity
    last_login_at TIMESTAMPTZ,
    last_activity_at TIMESTAMPTZ,

    -- Audit
    created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
    updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
    created_by UUID,
    updated_by UUID,
    deleted_at TIMESTAMPTZ,

    -- Constraints
    CONSTRAINT unique_email_per_tenant UNIQUE (tenant_id, email),
    CONSTRAINT valid_email CHECK (email ~* '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$')
);

-- Indexes
CREATE INDEX idx_users_tenant ON users.users(tenant_id) WHERE deleted_at IS NULL;
CREATE INDEX idx_users_email ON users.users(tenant_id, email) WHERE deleted_at IS NULL;
CREATE INDEX idx_users_status ON users.users(tenant_id, status) WHERE deleted_at IS NULL;
CREATE INDEX idx_users_owner ON users.users(tenant_id) WHERE is_owner = TRUE AND deleted_at IS NULL;

-- RLS
ALTER TABLE users.users ENABLE ROW LEVEL SECURITY;

CREATE POLICY users_tenant_isolation_select ON users.users
    FOR SELECT
    USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);

CREATE POLICY users_tenant_isolation_insert ON users.users
    FOR INSERT
    WITH CHECK (tenant_id = current_setting('app.current_tenant_id', true)::UUID);

CREATE POLICY users_tenant_isolation_update ON users.users
    FOR UPDATE
    USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID)
    WITH CHECK (tenant_id = current_setting('app.current_tenant_id', true)::UUID);

CREATE POLICY users_tenant_isolation_delete ON users.users
    FOR DELETE
    USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);

-- Trigger for updated_at
CREATE OR REPLACE FUNCTION users.update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = NOW();
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_users_updated_at
    BEFORE UPDATE ON users.users
    FOR EACH ROW
    EXECUTE FUNCTION users.update_updated_at();

-- Comments
COMMENT ON TABLE users.users IS 'User accounts within tenants';
COMMENT ON COLUMN users.users.is_owner IS 'Tenant owner/admin flag';
COMMENT ON COLUMN users.users.password_hash IS 'bcrypt hashed password, NULL for OAuth users';
COMMENT ON COLUMN users.users.mfa_secret IS 'TOTP secret for 2FA (encrypted)';
