-- Migration: Migrate roles, permissions, user_roles, and role_permissions to UUID
-- Date: 2025-01-27
-- Reference: GO-004, GO-001, GO-005, GO-006
-- 
-- This migration converts all RBAC tables from BIGINT to UUID to align with the models
-- and ensure consistency with the rest of the application.

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

-- ==========================================
-- TABLE: roles
-- ==========================================

DO $$
BEGIN
    -- Check if roles table exists and has BIGINT ID
    IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'roles') THEN
        IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'roles' AND column_name = 'id' AND data_type = 'bigint') THEN
            RAISE NOTICE 'Migrating roles.id from BIGINT to UUID';
            
            -- Add UUID column
            ALTER TABLE roles ADD COLUMN IF NOT EXISTS id_uuid UUID DEFAULT gen_random_uuid();
            
            -- Update role_permissions to use UUID (temporary mapping)
            ALTER TABLE role_permissions ADD COLUMN IF NOT EXISTS role_id_uuid UUID;
            UPDATE role_permissions rp
            SET role_id_uuid = r.id_uuid
            FROM roles r
            WHERE rp.role_id = r.id;
            
            -- Update user_roles to use UUID (temporary mapping)
            ALTER TABLE user_roles ADD COLUMN IF NOT EXISTS role_id_uuid UUID;
            UPDATE user_roles ur
            SET role_id_uuid = r.id_uuid
            FROM roles r
            WHERE ur.role_id = r.id;
            
            -- Drop foreign key constraints
            ALTER TABLE role_permissions DROP CONSTRAINT IF EXISTS role_permissions_role_id_fkey;
            ALTER TABLE user_roles DROP CONSTRAINT IF EXISTS user_roles_role_id_fkey;
            
            -- Drop old ID column and rename UUID column
            ALTER TABLE roles DROP CONSTRAINT IF EXISTS roles_pkey;
            ALTER TABLE roles DROP COLUMN id;
            ALTER TABLE roles RENAME COLUMN id_uuid TO id;
            ALTER TABLE roles ADD PRIMARY KEY (id);
            
            -- Update role_permissions
            ALTER TABLE role_permissions DROP COLUMN role_id;
            ALTER TABLE role_permissions RENAME COLUMN role_id_uuid TO role_id;
            ALTER TABLE role_permissions ADD CONSTRAINT role_permissions_role_id_fkey 
                FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE;
            
            -- Update user_roles
            ALTER TABLE user_roles DROP COLUMN role_id;
            ALTER TABLE user_roles RENAME COLUMN role_id_uuid TO role_id;
            ALTER TABLE user_roles ADD CONSTRAINT user_roles_role_id_fkey 
                FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE;
        END IF;
    END IF;
END $$;

-- ==========================================
-- TABLE: permissions
-- ==========================================

DO $$
BEGIN
    -- Check if permissions table exists and has BIGINT ID
    IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'permissions') THEN
        IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'permissions' AND column_name = 'id' AND data_type = 'bigint') THEN
            RAISE NOTICE 'Migrating permissions.id from BIGINT to UUID';
            
            -- Add UUID column
            ALTER TABLE permissions ADD COLUMN IF NOT EXISTS id_uuid UUID DEFAULT gen_random_uuid();
            
            -- Update role_permissions to use UUID (temporary mapping)
            ALTER TABLE role_permissions ADD COLUMN IF NOT EXISTS permission_id_uuid UUID;
            UPDATE role_permissions rp
            SET permission_id_uuid = p.id_uuid
            FROM permissions p
            WHERE rp.permission_id = p.id;
            
            -- Drop foreign key constraint
            ALTER TABLE role_permissions DROP CONSTRAINT IF EXISTS role_permissions_permission_id_fkey;
            
            -- Drop old ID column and rename UUID column
            ALTER TABLE permissions DROP CONSTRAINT IF EXISTS permissions_pkey;
            ALTER TABLE permissions DROP COLUMN id;
            ALTER TABLE permissions RENAME COLUMN id_uuid TO id;
            ALTER TABLE permissions ADD PRIMARY KEY (id);
            
            -- Update role_permissions
            ALTER TABLE role_permissions DROP COLUMN permission_id;
            ALTER TABLE role_permissions RENAME COLUMN permission_id_uuid TO permission_id;
            ALTER TABLE role_permissions ADD CONSTRAINT role_permissions_permission_id_fkey 
                FOREIGN KEY (permission_id) REFERENCES permissions(id) ON DELETE CASCADE;
            
            -- Recreate composite primary key
            ALTER TABLE role_permissions DROP CONSTRAINT IF EXISTS role_permissions_pkey;
            ALTER TABLE role_permissions ADD PRIMARY KEY (role_id, permission_id);
        END IF;
    END IF;
END $$;

-- ==========================================
-- TABLE: user_roles
-- ==========================================

DO $$
BEGIN
    -- Check if user_roles table exists and has BIGINT ID
    IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'user_roles') THEN
        IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'user_roles' AND column_name = 'id' AND data_type = 'bigint') THEN
            RAISE NOTICE 'Migrating user_roles.id from BIGINT to UUID';
            
            -- Add UUID column
            ALTER TABLE user_roles ADD COLUMN IF NOT EXISTS id_uuid UUID DEFAULT gen_random_uuid();
            
            -- Drop old ID column and rename UUID column
            ALTER TABLE user_roles DROP CONSTRAINT IF EXISTS user_roles_pkey;
            ALTER TABLE user_roles DROP COLUMN id;
            ALTER TABLE user_roles RENAME COLUMN id_uuid TO id;
            ALTER TABLE user_roles ADD PRIMARY KEY (id);
        END IF;
        
        -- Ensure user_id is UUID (should already be done by migration 047, but double-check)
        IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'user_roles' AND column_name = 'user_id' AND data_type = 'bigint') THEN
            RAISE NOTICE 'user_roles.user_id is still BIGINT, should have been migrated by 047. This is unexpected.';
        END IF;
        
        -- Ensure assigned_by is UUID if it exists
        IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'user_roles' AND column_name = 'assigned_by' AND data_type = 'bigint') THEN
            RAISE NOTICE 'Migrating user_roles.assigned_by from BIGINT to UUID';
            ALTER TABLE user_roles ADD COLUMN IF NOT EXISTS assigned_by_uuid UUID;
            UPDATE user_roles ur
            SET assigned_by_uuid = u.id
            FROM users u
            WHERE ur.assigned_by = u.id::bigint AND u.id IS NOT NULL;
            ALTER TABLE user_roles DROP COLUMN assigned_by;
            ALTER TABLE user_roles RENAME COLUMN assigned_by_uuid TO assigned_by;
        END IF;
    END IF;
END $$;

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

-- Recreate indexes if they don't exist
CREATE INDEX IF NOT EXISTS idx_user_roles_user_id ON user_roles(user_id);
CREATE INDEX IF NOT EXISTS idx_user_roles_role_id ON user_roles(role_id);
CREATE INDEX IF NOT EXISTS idx_role_permissions_role_id ON role_permissions(role_id);
CREATE INDEX IF NOT EXISTS idx_role_permissions_permission_id ON role_permissions(permission_id);

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

COMMENT ON TABLE roles IS 'System roles for RBAC (migrated to UUID)';
COMMENT ON TABLE permissions IS 'System permissions for RBAC (migrated to UUID)';
COMMENT ON TABLE user_roles IS 'User role assignments (migrated to UUID)';
COMMENT ON TABLE role_permissions IS 'Role permission mappings (migrated to UUID)';

