-- ============================================================================
-- RBAC Schema: Permissions Table
-- Granular permissions for Trading Platform SaaS
-- ============================================================================

-- ============================================================================
-- PERMISSIONS TABLE
-- Defines available permissions in the system
-- ============================================================================

CREATE TABLE IF NOT EXISTS rbac.permissions (
    -- Primary key
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    -- Permission identification
    code VARCHAR(100) NOT NULL UNIQUE,
    name VARCHAR(200) NOT NULL,
    description TEXT,

    -- Categorization
    module VARCHAR(50) NOT NULL,
    category VARCHAR(50) NOT NULL,

    -- Permission type
    action VARCHAR(20) NOT NULL
        CHECK (action IN ('create', 'read', 'update', 'delete', 'manage', 'execute')),

    -- Resource this permission applies to
    resource VARCHAR(100) NOT NULL,

    -- Is this a system permission (cannot be deleted)
    is_system BOOLEAN NOT NULL DEFAULT true,

    -- Status
    is_active BOOLEAN NOT NULL DEFAULT true,

    -- Audit fields
    created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
);

-- ============================================================================
-- INDEXES
-- ============================================================================

CREATE INDEX IF NOT EXISTS idx_permissions_code ON rbac.permissions(code);
CREATE INDEX IF NOT EXISTS idx_permissions_module ON rbac.permissions(module);
CREATE INDEX IF NOT EXISTS idx_permissions_category ON rbac.permissions(category);
CREATE INDEX IF NOT EXISTS idx_permissions_resource ON rbac.permissions(resource);
CREATE INDEX IF NOT EXISTS idx_permissions_is_active ON rbac.permissions(is_active);

-- ============================================================================
-- TRIGGERS
-- ============================================================================

CREATE OR REPLACE FUNCTION rbac.update_permissions_timestamp()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_permissions_updated_at
    BEFORE UPDATE ON rbac.permissions
    FOR EACH ROW
    EXECUTE FUNCTION rbac.update_permissions_timestamp();

-- ============================================================================
-- DEFAULT PERMISSIONS
-- ============================================================================

-- Organization/Tenant permissions
INSERT INTO rbac.permissions (code, name, description, module, category, action, resource) VALUES
('org:read', 'View Organization', 'View organization details and settings', 'organization', 'general', 'read', 'organization'),
('org:update', 'Update Organization', 'Update organization settings', 'organization', 'general', 'update', 'organization'),
('org:delete', 'Delete Organization', 'Delete the organization', 'organization', 'general', 'delete', 'organization'),
('org:billing:manage', 'Manage Billing', 'Manage billing and subscriptions', 'organization', 'billing', 'manage', 'billing')
ON CONFLICT (code) DO NOTHING;

-- User management permissions
INSERT INTO rbac.permissions (code, name, description, module, category, action, resource) VALUES
('users:read', 'View Users', 'View user list and details', 'users', 'management', 'read', 'users'),
('users:create', 'Create Users', 'Create new users', 'users', 'management', 'create', 'users'),
('users:update', 'Update Users', 'Update user information', 'users', 'management', 'update', 'users'),
('users:delete', 'Delete Users', 'Delete or deactivate users', 'users', 'management', 'delete', 'users'),
('users:invite', 'Invite Users', 'Send invitations to new users', 'users', 'management', 'execute', 'invitations')
ON CONFLICT (code) DO NOTHING;

-- Role management permissions
INSERT INTO rbac.permissions (code, name, description, module, category, action, resource) VALUES
('roles:read', 'View Roles', 'View roles and permissions', 'rbac', 'management', 'read', 'roles'),
('roles:create', 'Create Roles', 'Create custom roles', 'rbac', 'management', 'create', 'roles'),
('roles:update', 'Update Roles', 'Update role permissions', 'rbac', 'management', 'update', 'roles'),
('roles:delete', 'Delete Roles', 'Delete custom roles', 'rbac', 'management', 'delete', 'roles'),
('roles:assign', 'Assign Roles', 'Assign roles to users', 'rbac', 'management', 'execute', 'role_assignments')
ON CONFLICT (code) DO NOTHING;

-- Wallet permissions
INSERT INTO rbac.permissions (code, name, description, module, category, action, resource) VALUES
('wallet:read', 'View Wallet', 'View wallet balance and transactions', 'wallet', 'finance', 'read', 'wallet'),
('wallet:deposit', 'Deposit Credits', 'Add credits to wallet', 'wallet', 'finance', 'execute', 'deposits'),
('wallet:withdraw', 'Withdraw Credits', 'Withdraw credits from wallet', 'wallet', 'finance', 'execute', 'withdrawals'),
('wallet:transfer', 'Transfer Credits', 'Transfer credits between wallets', 'wallet', 'finance', 'execute', 'transfers')
ON CONFLICT (code) DO NOTHING;

-- Products/Marketplace permissions
INSERT INTO rbac.permissions (code, name, description, module, category, action, resource) VALUES
('products:read', 'View Products', 'View marketplace products', 'products', 'marketplace', 'read', 'products'),
('products:purchase', 'Purchase Products', 'Purchase products from marketplace', 'products', 'marketplace', 'execute', 'purchases'),
('products:create', 'Create Products', 'Create new products (for sellers)', 'products', 'marketplace', 'create', 'products'),
('products:update', 'Update Products', 'Update product information', 'products', 'marketplace', 'update', 'products'),
('products:delete', 'Delete Products', 'Delete products', 'products', 'marketplace', 'delete', 'products')
ON CONFLICT (code) DO NOTHING;

-- VIP/Subscription permissions
INSERT INTO rbac.permissions (code, name, description, module, category, action, resource) VALUES
('vip:read', 'View VIP Plans', 'View VIP subscription plans', 'vip', 'subscriptions', 'read', 'vip_plans'),
('vip:subscribe', 'Subscribe to VIP', 'Subscribe to VIP plans', 'vip', 'subscriptions', 'execute', 'subscriptions'),
('vip:manage', 'Manage VIP Plans', 'Create and manage VIP plans', 'vip', 'subscriptions', 'manage', 'vip_plans')
ON CONFLICT (code) DO NOTHING;

-- Investment/Agents permissions
INSERT INTO rbac.permissions (code, name, description, module, category, action, resource) VALUES
('agents:read', 'View Agents', 'View trading agents', 'investment', 'trading', 'read', 'agents'),
('agents:allocate', 'Allocate to Agents', 'Allocate funds to agents', 'investment', 'trading', 'execute', 'allocations'),
('agents:manage', 'Manage Agents', 'Create and configure agents', 'investment', 'trading', 'manage', 'agents')
ON CONFLICT (code) DO NOTHING;

-- Predictions permissions
INSERT INTO rbac.permissions (code, name, description, module, category, action, resource) VALUES
('predictions:read', 'View Predictions', 'View predictions and packages', 'predictions', 'analytics', 'read', 'predictions'),
('predictions:purchase', 'Purchase Predictions', 'Purchase prediction packages', 'predictions', 'analytics', 'execute', 'purchases'),
('predictions:create', 'Create Predictions', 'Create prediction packages', 'predictions', 'analytics', 'create', 'predictions')
ON CONFLICT (code) DO NOTHING;

-- Audit/Reports permissions
INSERT INTO rbac.permissions (code, name, description, module, category, action, resource) VALUES
('audit:read', 'View Audit Logs', 'View audit trail and logs', 'audit', 'compliance', 'read', 'audit_logs'),
('reports:read', 'View Reports', 'View analytics and reports', 'reports', 'analytics', 'read', 'reports'),
('reports:export', 'Export Reports', 'Export reports and data', 'reports', 'analytics', 'execute', 'exports')
ON CONFLICT (code) DO NOTHING;

-- ============================================================================
-- GRANTS
-- ============================================================================

GRANT SELECT ON rbac.permissions TO trading_user;
-- Only admins should be able to modify permissions
GRANT INSERT, UPDATE, DELETE ON rbac.permissions TO trading_admin;

-- ============================================================================
-- COMMENTS
-- ============================================================================

COMMENT ON TABLE rbac.permissions IS 'System-wide permissions for RBAC';
COMMENT ON COLUMN rbac.permissions.code IS 'Unique permission code in format module:action or module:resource:action';
COMMENT ON COLUMN rbac.permissions.module IS 'Feature module this permission belongs to';
COMMENT ON COLUMN rbac.permissions.action IS 'CRUD action or special action (manage, execute)';
COMMENT ON COLUMN rbac.permissions.resource IS 'Resource this permission applies to';
