-- =====================================================
-- 修复触发器冲突脚本
-- 解决 "trigger already exists" 错误
-- =====================================================

-- 清理所有可能存在的触发器
DO $$
BEGIN
    -- 删除用户角色相关触发器
    DROP TRIGGER IF EXISTS trigger_update_user_roles_updated_at ON public.user_roles;
    DROP TRIGGER IF EXISTS on_auth_user_created ON auth.users;
    
    -- 删除可能存在的旧版本触发器
    DROP TRIGGER IF EXISTS update_user_roles_updated_at ON public.user_roles;
    DROP TRIGGER IF EXISTS handle_new_user_trigger ON auth.users;
    
    RAISE NOTICE '✅ 已清理所有现有触发器';
END $$;

-- 清理可能存在的函数冲突
DO $$
BEGIN
    -- 删除函数（CASCADE 会自动删除依赖的触发器）
    DROP FUNCTION IF EXISTS public.update_user_roles_updated_at() CASCADE;
    DROP FUNCTION IF EXISTS public.handle_new_user() CASCADE;
    DROP FUNCTION IF EXISTS public.update_user_role(UUID, TEXT, UUID) CASCADE;
    DROP FUNCTION IF EXISTS public.get_user_role(UUID) CASCADE;
    DROP FUNCTION IF EXISTS public.batch_update_user_roles(JSONB, UUID) CASCADE;
    DROP FUNCTION IF EXISTS public.sync_user_role_metadata(UUID) CASCADE;
    
    RAISE NOTICE '✅ 已清理可能冲突的函数';
END $$;

-- 重新创建核心函数
-- 1. 更新时间戳函数
CREATE OR REPLACE FUNCTION public.update_user_roles_updated_at()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = NOW();
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- 2. 同步用户角色到元数据的函数
CREATE OR REPLACE FUNCTION public.sync_user_role_metadata(target_user_id UUID)
RETURNS BOOLEAN AS $$
DECLARE
    user_role_record RECORD;
BEGIN
    -- 获取用户角色信息
    SELECT role, class_id, school_id, department, permissions, is_active
    INTO user_role_record
    FROM public.user_roles 
    WHERE user_id = target_user_id AND is_active = true;
    
    IF FOUND THEN
        -- 更新 auth.users 的元数据
        UPDATE auth.users 
        SET raw_user_meta_data = COALESCE(raw_user_meta_data, '{}'::jsonb) || 
            jsonb_build_object(
                'user_role', user_role_record.role,
                'class_id', user_role_record.class_id,
                'school_id', user_role_record.school_id,
                'department', user_role_record.department,
                'permissions', user_role_record.permissions,
                'role_synced_at', extract(epoch from now())
            )
        WHERE id = target_user_id;
        
        RETURN true;
    ELSE
        -- 用户没有活跃角色，清除角色信息
        UPDATE auth.users 
        SET raw_user_meta_data = COALESCE(raw_user_meta_data, '{}'::jsonb) || 
            jsonb_build_object(
                'user_role', 'inactive',
                'role_synced_at', extract(epoch from now())
            )
        WHERE id = target_user_id;
        
        RETURN false;
    END IF;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

-- 3. 自动为新用户分配角色的函数
CREATE OR REPLACE FUNCTION public.handle_new_user()
RETURNS TRIGGER AS $$
DECLARE
    user_role TEXT := 'student'; -- 默认角色
    user_email TEXT := NEW.email;
    user_domain TEXT;
BEGIN
    -- 提取邮箱域名
    user_domain := split_part(user_email, '@', 2);
    
    -- 根据邮箱域名或特定规则分配角色
    CASE 
        WHEN user_domain IN ('teacher.edu', 'faculty.edu', 'staff.edu') THEN
            user_role := 'teacher';
        WHEN user_domain IN ('admin.edu', 'management.edu') THEN
            user_role := 'admin';
        WHEN user_email LIKE '%admin%' OR user_email LIKE '%manager%' THEN
            user_role := 'admin';
        WHEN user_email LIKE '%teacher%' OR user_email LIKE '%faculty%' THEN
            user_role := 'teacher';
        ELSE
            user_role := 'student';
    END CASE;
    
    -- 插入角色记录
    INSERT INTO public.user_roles (user_id, role, created_by)
    VALUES (NEW.id, user_role, NEW.id);
    
    -- 同步到元数据
    PERFORM public.sync_user_role_metadata(NEW.id);
    
    RAISE NOTICE '✅ 为用户 % 分配角色: %', NEW.email, user_role;
    
    RETURN NEW;
EXCEPTION WHEN OTHERS THEN
    RAISE WARNING '⚠️ 为用户 % 分配角色失败: %', NEW.email, SQLERRM;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

-- 4. 获取用户角色的函数（支持缓存）
CREATE OR REPLACE FUNCTION public.get_user_role(target_user_id UUID DEFAULT auth.uid())
RETURNS TEXT AS $$
DECLARE
    user_role TEXT;
    cached_role TEXT;
    role_synced_at NUMERIC;
BEGIN
    -- 如果没有用户ID，返回匿名
    IF target_user_id IS NULL THEN
        RETURN 'anonymous';
    END IF;
    
    -- 尝试从 auth.users 元数据获取缓存角色
    SELECT 
        raw_user_meta_data->>'user_role',
        (raw_user_meta_data->>'role_synced_at')::numeric
    INTO cached_role, role_synced_at
    FROM auth.users 
    WHERE id = target_user_id;
    
    -- 如果缓存新鲜（5分钟内），直接返回
    IF cached_role IS NOT NULL AND role_synced_at IS NOT NULL 
       AND (extract(epoch from now()) - role_synced_at) < 300 THEN
        RETURN cached_role;
    END IF;
    
    -- 从角色表获取最新角色
    SELECT role INTO user_role 
    FROM public.user_roles 
    WHERE user_id = target_user_id AND is_active = true;
    
    -- 如果找到角色，同步到元数据
    IF FOUND THEN
        PERFORM public.sync_user_role_metadata(target_user_id);
        RETURN user_role;
    ELSE
        RETURN 'student'; -- 默认角色
    END IF;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

-- 重新创建触发器
DO $$
BEGIN
    -- 创建更新时间戳触发器
    CREATE TRIGGER trigger_update_user_roles_updated_at
        BEFORE UPDATE ON public.user_roles
        FOR EACH ROW
        EXECUTE FUNCTION public.update_user_roles_updated_at();
    
    -- 创建新用户触发器
    CREATE TRIGGER on_auth_user_created
        AFTER INSERT ON auth.users
        FOR EACH ROW
        EXECUTE FUNCTION public.handle_new_user();
    
    RAISE NOTICE '✅ 触发器重建完成';
END $$;

-- 验证触发器是否正确创建
DO $$
DECLARE
    trigger_count INTEGER;
BEGIN
    SELECT COUNT(*) INTO trigger_count
    FROM information_schema.triggers
    WHERE trigger_schema = 'public'
    AND trigger_name IN ('trigger_update_user_roles_updated_at', 'on_auth_user_created');
    
    IF trigger_count >= 2 THEN
        RAISE NOTICE '🎉 触发器验证通过: % 个触发器已创建', trigger_count;
    ELSE
        RAISE WARNING '⚠️ 触发器验证失败: 只找到 % 个触发器', trigger_count;
    END IF;
END $$;

-- 验证函数是否正确创建
DO $$
DECLARE
    function_count INTEGER;
BEGIN
    SELECT COUNT(*) INTO function_count
    FROM information_schema.routines
    WHERE routine_schema = 'public'
    AND routine_name IN (
        'update_user_roles_updated_at',
        'handle_new_user',
        'sync_user_role_metadata',
        'get_user_role'
    );
    
    IF function_count >= 4 THEN
        RAISE NOTICE '🎉 函数验证通过: % 个函数已创建', function_count;
    ELSE
        RAISE WARNING '⚠️ 函数验证失败: 只找到 % 个函数', function_count;
    END IF;
END $$;

-- 完成消息
SELECT 
    '🔧 触发器修复完成' as status,
    '现在可以安全地执行其他SQL脚本' as message;
