-- =====================================================
-- 消息系统权限模式管理器
-- 在开发模式和生产模式之间快速切换
-- =====================================================

-- 创建权限模式管理函数
CREATE OR REPLACE FUNCTION public.get_permission_mode()
RETURNS TABLE (
    mode TEXT,
    description TEXT,
    dev_policies INTEGER,
    normal_policies INTEGER,
    dev_functions INTEGER
)
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
DECLARE
    v_dev_policies INTEGER;
    v_normal_policies INTEGER;
    v_dev_functions INTEGER;
    v_mode TEXT;
    v_description TEXT;
BEGIN
    -- 统计开发模式策略
    SELECT COUNT(*) INTO v_dev_policies
    FROM pg_policies 
    WHERE schemaname = 'public' 
    AND (policyname LIKE 'dev_%' OR policyname LIKE 'authenticated_full_%');
    
    -- 统计正常模式策略
    SELECT COUNT(*) INTO v_normal_policies
    FROM pg_policies 
    WHERE schemaname = 'public' 
    AND tablename IN ('ak_messages', 'ak_message_recipients', 'ak_message_groups', 
                     'ak_message_group_members', 'ak_message_templates', 
                     'ak_user_message_preferences', 'ak_message_stats', 'ak_message_types')
    AND NOT (policyname LIKE 'dev_%' OR policyname LIKE 'authenticated_full_%');
    
    -- 统计开发函数
    SELECT COUNT(*) INTO v_dev_functions
    FROM information_schema.routines
    WHERE routine_schema = 'public'
    AND routine_name LIKE 'dev_%';
    
    -- 判断当前模式
    IF v_dev_policies > 0 THEN
        v_mode := '🔓 开发模式';
        v_description := '所有authenticated用户拥有完全权限';
    ELSIF v_normal_policies > 0 THEN
        v_mode := '🔒 生产模式';
        v_description := '基于角色的权限控制';
    ELSE
        v_mode := '❓ 未知模式';
        v_description := '权限策略可能未正确设置';
    END IF;
    
    RETURN QUERY SELECT 
        v_mode,
        v_description,
        v_dev_policies,
        v_normal_policies,
        v_dev_functions;
END $$;

-- 权限策略详情查看函数
CREATE OR REPLACE FUNCTION public.list_message_policies()
RETURNS TABLE (
    table_name TEXT,
    policy_name TEXT,
    policy_type TEXT,
    policy_mode TEXT
)
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
BEGIN
    RETURN QUERY
    SELECT 
        p.tablename::TEXT,
        p.policyname::TEXT,
        CASE 
            WHEN p.cmd = 'r' THEN 'SELECT'
            WHEN p.cmd = 'a' THEN 'INSERT'
            WHEN p.cmd = 'w' THEN 'UPDATE'
            WHEN p.cmd = 'd' THEN 'DELETE'
            WHEN p.cmd = '*' THEN 'ALL'
            ELSE p.cmd::TEXT
        END as policy_type,
        CASE 
            WHEN p.policyname LIKE 'dev_%' OR p.policyname LIKE 'authenticated_full_%' THEN '🔓 开发'
            ELSE '🔒 生产'
        END as policy_mode
    FROM pg_policies p
    WHERE p.schemaname = 'public' 
    AND p.tablename IN ('ak_messages', 'ak_message_recipients', 'ak_message_groups', 
                       'ak_message_group_members', 'ak_message_templates', 
                       'ak_user_message_preferences', 'ak_message_stats', 'ak_message_types')
    ORDER BY p.tablename, p.policyname;
END $$;

-- 快速切换到开发模式
CREATE OR REPLACE FUNCTION public.switch_to_dev_mode()
RETURNS TEXT
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
DECLARE
    table_names TEXT[] := ARRAY[
        'ak_message_types', 'ak_messages', 'ak_message_recipients',
        'ak_message_groups', 'ak_message_group_members', 'ak_message_templates',
        'ak_user_message_preferences', 'ak_message_stats'
    ];
    table_name TEXT;
    r RECORD;
    policy_count INTEGER := 0;
BEGIN
    -- 清理现有策略
    FOREACH table_name IN ARRAY table_names LOOP
        FOR r IN 
            SELECT policyname 
            FROM pg_policies 
            WHERE schemaname = 'public' AND tablename = table_name
        LOOP
            EXECUTE format('DROP POLICY IF EXISTS %I ON public.%I', r.policyname, table_name);
        END LOOP;
        
        -- 创建开放策略
        EXECUTE format('
            CREATE POLICY "dev_open_access_%s" ON public.%I
            FOR ALL USING (auth.role() = ''authenticated'')
            WITH CHECK (auth.role() = ''authenticated'')
        ', replace(table_name, 'ak_', ''), table_name);
        
        policy_count := policy_count + 1;
    END LOOP;
    
    RETURN format('🔓 已切换到开发模式，创建了 %s 个开放策略', policy_count);
END $$;

-- 快速切换到生产模式
CREATE OR REPLACE FUNCTION public.switch_to_prod_mode()
RETURNS TEXT
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
DECLARE
    table_names TEXT[] := ARRAY[
        'ak_message_types', 'ak_messages', 'ak_message_recipients',
        'ak_message_groups', 'ak_message_group_members', 'ak_message_templates',
        'ak_user_message_preferences', 'ak_message_stats'
    ];
    table_name TEXT;
    r RECORD;
    deleted_count INTEGER := 0;
BEGIN
    -- 删除所有开发模式策略
    FOREACH table_name IN ARRAY table_names LOOP
        FOR r IN 
            SELECT policyname 
            FROM pg_policies 
            WHERE schemaname = 'public' 
            AND tablename = table_name
            AND (policyname LIKE 'dev_%' OR policyname LIKE 'authenticated_full_%')
        LOOP
            EXECUTE format('DROP POLICY IF EXISTS %I ON public.%I', r.policyname, table_name);
            deleted_count := deleted_count + 1;
        END LOOP;
    END LOOP;
    
    -- 这里应该运行完整的生产权限策略创建
    -- 为了简化，我们只清理开发策略
    -- 实际部署时需要运行 restore_normal_permissions.sql
    
    RETURN format('🔒 已清理 %s 个开发策略，请运行 restore_normal_permissions.sql 完成生产模式设置', deleted_count);
END $$;

-- 权限健康检查函数
CREATE OR REPLACE FUNCTION public.check_permission_health()
RETURNS TABLE (
    check_item TEXT,
    status TEXT,
    details TEXT,
    recommendation TEXT
)
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
DECLARE
    v_rls_enabled INTEGER;
    v_auth_functions INTEGER;
    v_role_functions INTEGER;
    v_conflicting_policies INTEGER;
BEGIN
    -- 检查RLS是否启用
    SELECT COUNT(*) INTO v_rls_enabled
    FROM pg_class c
    JOIN pg_namespace n ON c.relnamespace = n.oid
    WHERE n.nspname = 'public'
    AND c.relname IN ('ak_messages', 'ak_message_recipients', 'ak_message_groups', 
                     'ak_message_group_members', 'ak_message_templates', 
                     'ak_user_message_preferences', 'ak_message_stats', 'ak_message_types')
    AND c.relrowsecurity = true;
    
    -- 检查认证相关函数
    SELECT COUNT(*) INTO v_auth_functions
    FROM information_schema.routines
    WHERE routine_schema = 'public'
    AND routine_name IN ('get_user_role', 'is_group_member');
    
    -- 检查用户角色函数
    SELECT COUNT(*) INTO v_role_functions
    FROM information_schema.routines
    WHERE routine_schema = 'public'
    AND routine_name LIKE '%role%';
    
    -- 检查冲突策略
    SELECT COUNT(*) INTO v_conflicting_policies
    FROM pg_policies 
    WHERE schemaname = 'public'
    AND tablename IN ('ak_messages', 'ak_message_recipients', 'ak_message_groups', 
                     'ak_message_group_members', 'ak_message_templates', 
                     'ak_user_message_preferences', 'ak_message_stats', 'ak_message_types')
    GROUP BY tablename, cmd
    HAVING COUNT(*) > 3; -- 如果同一表同一操作有超过3个策略可能有问题
    
    -- RLS启用检查
    RETURN QUERY SELECT 
        'RLS启用状态'::TEXT,
        CASE WHEN v_rls_enabled >= 8 THEN '✅ 正常' ELSE '⚠️ 异常' END,
        format('%s/8 个表启用了RLS', v_rls_enabled),
        CASE WHEN v_rls_enabled < 8 THEN '运行完整部署脚本启用RLS' ELSE '无需操作' END;
    
    -- 认证函数检查
    RETURN QUERY SELECT 
        '认证函数'::TEXT,
        CASE WHEN v_auth_functions >= 2 THEN '✅ 正常' ELSE '⚠️ 缺失' END,
        format('找到 %s 个认证相关函数', v_auth_functions),
        CASE WHEN v_auth_functions < 2 THEN '运行 supabase_auth_complete_setup.sql' ELSE '无需操作' END;
    
    -- 策略冲突检查
    RETURN QUERY SELECT 
        '策略冲突'::TEXT,
        CASE WHEN v_conflicting_policies = 0 THEN '✅ 正常' ELSE '⚠️ 可能存在' END,
        format('发现 %s 个潜在冲突', v_conflicting_policies),
        CASE WHEN v_conflicting_policies > 0 THEN '检查并清理重复策略' ELSE '无需操作' END;
        
END $$;

-- =============================================================================
-- 使用示例和说明
-- =============================================================================

/*
-- 使用示例：

-- 1. 查看当前权限模式
SELECT * FROM public.get_permission_mode();

-- 2. 查看所有权限策略
SELECT * FROM public.list_message_policies();

-- 3. 切换到开发模式
SELECT public.switch_to_dev_mode();

-- 4. 切换到生产模式（仅清理，需要手动运行完整脚本）
SELECT public.switch_to_prod_mode();

-- 5. 权限健康检查
SELECT * FROM public.check_permission_health();

-- 6. 快速检查当前状态
SELECT 
    mode,
    description,
    CASE 
        WHEN dev_policies > 0 THEN '⚠️ 开发环境权限'
        WHEN normal_policies > 0 THEN '✅ 生产环境权限'
        ELSE '❌ 权限未配置'
    END as security_level
FROM public.get_permission_mode();
*/

-- 创建权限管理视图（只读）
CREATE OR REPLACE VIEW public.permission_dashboard AS
SELECT 
    pm.mode,
    pm.description,
    pm.dev_policies,
    pm.normal_policies,
    pm.dev_functions,
    CASE 
        WHEN pm.dev_policies > 0 THEN '⚠️ 开发模式 - 权限开放'
        WHEN pm.normal_policies > 0 THEN '✅ 生产模式 - 权限受控'
        ELSE '❌ 未知模式 - 需要检查'
    END as security_status,
    NOW() as checked_at
FROM public.get_permission_mode() pm;

-- 完成提示
SELECT 
    '🛠️ 权限管理器' as component,
    '已创建' as status,
    'get_permission_mode(), switch_to_dev_mode(), switch_to_prod_mode()' as functions,
    'permission_dashboard 视图可查看实时状态' as info;
