-- Analytics 页面 RPC 函数 SQL 语句
-- 运动训练监测与AI评估平台 - 教师数据分析功能

-- 1. 获取教师统计数据 (get_teacher_analytics)
CREATE OR REPLACE FUNCTION public.get_teacher_analytics(
    p_teacher_id uuid DEFAULT NULL,
    p_start_date date DEFAULT NULL,
    p_end_date date DEFAULT NULL
)
RETURNS TABLE(
    total_students integer,
    total_assignments integer,
    completion_rate numeric,
    average_score numeric,
    active_classes integer,
    total_submissions integer,
    pending_reviews integer,
    graded_submissions integer
) 
LANGUAGE plpgsql 
SECURITY DEFINER
AS $$
DECLARE
    v_teacher_id uuid;
    v_start_date date;
    v_end_date date;
BEGIN
    -- 参数处理
    v_teacher_id := COALESCE(p_teacher_id, auth.uid());
    v_start_date := COALESCE(p_start_date, CURRENT_DATE - INTERVAL '30 days');
    v_end_date := COALESCE(p_end_date, CURRENT_DATE);
    
    -- 确保是教师用户
    IF NOT EXISTS (
        SELECT 1 FROM public.ak_users 
        WHERE id = v_teacher_id AND role = 'teacher'
    ) THEN
        RAISE EXCEPTION '用户不是教师或不存在';
    END IF;

    RETURN QUERY
    WITH teacher_classes AS (
        -- 获取教师关联的班级
        SELECT DISTINCT uc.class_id
        FROM public.ak_user_classes uc
        WHERE uc.user_id = v_teacher_id 
        AND uc.role = 'teacher'
    ),
    class_students AS (
        -- 获取班级中的学生
        SELECT DISTINCT uc.user_id as student_id, uc.class_id
        FROM public.ak_user_classes uc
        INNER JOIN teacher_classes tc ON uc.class_id = tc.class_id
        WHERE uc.role = 'student'
    ),
    teacher_assignments AS (
        -- 获取教师的作业
        SELECT a.*
        FROM public.ak_assignments a
        INNER JOIN teacher_classes tc ON a.class_id = tc.class_id
        WHERE a.created_at::date BETWEEN v_start_date AND v_end_date
    ),
    assignment_stats AS (
        -- 作业统计
        SELECT 
            COUNT(DISTINCT cs.student_id) as student_count,
            COUNT(DISTINCT ta.id) as assignment_count,
            COUNT(asub.id) as total_submission_count,
            COUNT(CASE WHEN asub.score IS NOT NULL THEN 1 END) as graded_count,
            COUNT(CASE WHEN asub.score IS NULL AND asub.id IS NOT NULL THEN 1 END) as pending_count,
            AVG(CASE WHEN asub.score IS NOT NULL THEN asub.score END) as avg_score
        FROM class_students cs
        CROSS JOIN teacher_assignments ta
        LEFT JOIN public.ak_assignment_submissions asub 
            ON ta.id = asub.assignment_id 
            AND cs.student_id = asub.student_id
    )
    SELECT 
        COALESCE(ast.student_count, 0)::integer,
        COALESCE(ast.assignment_count, 0)::integer,
        CASE 
            WHEN ast.student_count > 0 AND ast.assignment_count > 0 
            THEN ROUND((ast.total_submission_count::numeric / (ast.student_count * ast.assignment_count) * 100), 2)
            ELSE 0
        END,
        COALESCE(ROUND(ast.avg_score, 2), 0),
        (SELECT COUNT(DISTINCT class_id) FROM teacher_classes)::integer,
        COALESCE(ast.total_submission_count, 0)::integer,
        COALESCE(ast.pending_count, 0)::integer,
        COALESCE(ast.graded_count, 0)::integer
    FROM assignment_stats ast;
END;
$$;

-- 为函数添加注释
COMMENT ON FUNCTION public.get_teacher_analytics IS '获取教师统计数据：学生数、作业数、完成率、平均分等';

-- 2. 获取优秀学员排行 (get_top_performers)
CREATE OR REPLACE FUNCTION public.get_top_performers(
    p_teacher_id uuid DEFAULT NULL,
    p_start_date date DEFAULT NULL,
    p_end_date date DEFAULT NULL,
    p_limit integer DEFAULT 10
)
RETURNS TABLE(
    student_id uuid,
    name text,
    username text,
    avatar_url text,
    score numeric,
    submission_count integer,
    completion_rate numeric,
    class_name text,
    rank_position integer
) 
LANGUAGE plpgsql 
SECURITY DEFINER
AS $$
DECLARE
    v_teacher_id uuid;
    v_start_date date;
    v_end_date date;
    v_limit integer;
BEGIN
    -- 参数处理
    v_teacher_id := COALESCE(p_teacher_id, auth.uid());
    v_start_date := COALESCE(p_start_date, CURRENT_DATE - INTERVAL '30 days');
    v_end_date := COALESCE(p_end_date, CURRENT_DATE);
    v_limit := COALESCE(p_limit, 10);
    
    -- 确保是教师用户
    IF NOT EXISTS (
        SELECT 1 FROM public.ak_users 
        WHERE id = v_teacher_id AND role = 'teacher'
    ) THEN
        RAISE EXCEPTION '用户不是教师或不存在';
    END IF;

    RETURN QUERY
    WITH teacher_classes AS (
        -- 获取教师关联的班级
        SELECT DISTINCT uc.class_id, c.name as class_name
        FROM public.ak_user_classes uc
        INNER JOIN public.ak_classes c ON uc.class_id = c.id
        WHERE uc.user_id = v_teacher_id 
        AND uc.role = 'teacher'
    ),
    class_students AS (
        -- 获取班级中的学生
        SELECT DISTINCT uc.user_id as student_id, uc.class_id, tc.class_name
        FROM public.ak_user_classes uc
        INNER JOIN teacher_classes tc ON uc.class_id = tc.class_id
        WHERE uc.role = 'student'
    ),
    teacher_assignments AS (
        -- 获取教师的作业
        SELECT a.*
        FROM public.ak_assignments a
        INNER JOIN teacher_classes tc ON a.class_id = tc.class_id
        WHERE a.created_at::date BETWEEN v_start_date AND v_end_date
    ),
    student_performance AS (
        -- 学生表现统计
        SELECT 
            cs.student_id,
            cs.class_name,
            u.username,
            COALESCE(up.avatar_url, u.avatar_url) as avatar_url,
            COUNT(asub.id) as submission_count,
            COUNT(ta.id) as total_assignments,
            AVG(CASE WHEN asub.score IS NOT NULL THEN asub.score END) as avg_score,
            CASE 
                WHEN COUNT(ta.id) > 0 
                THEN ROUND((COUNT(asub.id)::numeric / COUNT(ta.id) * 100), 2)
                ELSE 0
            END as completion_rate
        FROM class_students cs
        INNER JOIN public.ak_users u ON cs.student_id = u.id
        LEFT JOIN public.ak_user_profiles up ON u.id = up.user_id
        CROSS JOIN teacher_assignments ta
        LEFT JOIN public.ak_assignment_submissions asub 
            ON ta.id = asub.assignment_id 
            AND cs.student_id = asub.student_id
        GROUP BY cs.student_id, cs.class_name, u.username, up.avatar_url, u.avatar_url
        HAVING COUNT(asub.id) > 0  -- 只显示有提交记录的学生
    ),
    ranked_students AS (
        SELECT 
            sp.*,
            ROW_NUMBER() OVER (
                ORDER BY 
                    COALESCE(sp.avg_score, 0) DESC, 
                    sp.completion_rate DESC, 
                    sp.submission_count DESC
            ) as rank_pos
        FROM student_performance sp
    )
    SELECT 
        rs.student_id,
        COALESCE(u.username, '未知学员') as name,
        rs.username,
        rs.avatar_url,
        COALESCE(ROUND(rs.avg_score, 2), 0) as score,
        rs.submission_count::integer,
        rs.completion_rate,
        rs.class_name,
        rs.rank_pos::integer
    FROM ranked_students rs
    INNER JOIN public.ak_users u ON rs.student_id = u.id
    WHERE rs.rank_pos <= v_limit
    ORDER BY rs.rank_pos;
END;
$$;

-- 为函数添加注释
COMMENT ON FUNCTION public.get_top_performers IS '获取优秀学员排行榜：按平均分、完成率排序';

-- 3. 获取图表数据 (get_chart_data)
CREATE OR REPLACE FUNCTION public.get_chart_data(
    p_teacher_id uuid DEFAULT NULL,
    p_start_date date DEFAULT NULL,
    p_end_date date DEFAULT NULL,
    p_type text DEFAULT 'completion_rate'
)
RETURNS TABLE(
    date_key date,
    value numeric,
    label text,
    count integer
) 
LANGUAGE plpgsql 
SECURITY DEFINER
AS $$
DECLARE
    v_teacher_id uuid;
    v_start_date date;
    v_end_date date;
    v_type text;
BEGIN
    -- 参数处理
    v_teacher_id := COALESCE(p_teacher_id, auth.uid());
    v_start_date := COALESCE(p_start_date, CURRENT_DATE - INTERVAL '30 days');
    v_end_date := COALESCE(p_end_date, CURRENT_DATE);
    v_type := COALESCE(p_type, 'completion_rate');
    
    -- 确保是教师用户
    IF NOT EXISTS (
        SELECT 1 FROM public.ak_users 
        WHERE id = v_teacher_id AND role = 'teacher'
    ) THEN
        RAISE EXCEPTION '用户不是教师或不存在';
    END IF;

    -- 根据类型返回不同的图表数据
    IF v_type = 'completion_rate' THEN
        -- 作业完成率趋势
        RETURN QUERY
        WITH teacher_classes AS (
            SELECT DISTINCT uc.class_id
            FROM public.ak_user_classes uc
            WHERE uc.user_id = v_teacher_id AND uc.role = 'teacher'
        ),
        date_series AS (
            SELECT generate_series(v_start_date, v_end_date, '1 day'::interval)::date as date_key
        ),
        daily_stats AS (
            SELECT 
                ds.date_key,
                COUNT(DISTINCT a.id) as assignments_due,
                COUNT(asub.id) as submissions_made
            FROM date_series ds
            LEFT JOIN public.ak_assignments a ON ds.date_key = a.due_date::date
                AND a.class_id IN (SELECT class_id FROM teacher_classes)
            LEFT JOIN public.ak_assignment_submissions asub ON a.id = asub.assignment_id
                AND asub.submit_time::date <= ds.date_key
            GROUP BY ds.date_key
        )
        SELECT 
            dst.date_key,
            CASE 
                WHEN dst.assignments_due > 0 
                THEN ROUND((dst.submissions_made::numeric / dst.assignments_due * 100), 2)
                ELSE 0
            END as value,
            '完成率' as label,
            dst.submissions_made::integer as count
        FROM daily_stats dst
        WHERE dst.assignments_due > 0 OR dst.submissions_made > 0
        ORDER BY dst.date_key;
        
    ELSIF v_type = 'score_distribution' THEN
        -- 成绩分布
        RETURN QUERY
        WITH teacher_classes AS (
            SELECT DISTINCT uc.class_id
            FROM public.ak_user_classes uc
            WHERE uc.user_id = v_teacher_id AND uc.role = 'teacher'
        ),
        score_ranges AS (
            SELECT 
                CASE 
                    WHEN asub.score >= 90 THEN '90-100'
                    WHEN asub.score >= 80 THEN '80-89'
                    WHEN asub.score >= 70 THEN '70-79'
                    WHEN asub.score >= 60 THEN '60-69'
                    ELSE '60以下'
                END as score_range,
                asub.score
            FROM public.ak_assignment_submissions asub
            INNER JOIN public.ak_assignments a ON asub.assignment_id = a.id
            INNER JOIN teacher_classes tc ON a.class_id = tc.class_id
            WHERE asub.score IS NOT NULL
            AND asub.submit_time::date BETWEEN v_start_date AND v_end_date
        )
        SELECT 
            v_start_date as date_key,  -- 使用开始日期作为占位符
            0::numeric as value,       -- 不使用value字段
            sr.score_range as label,
            COUNT(*)::integer as count
        FROM score_ranges sr
        GROUP BY sr.score_range
        ORDER BY 
            CASE sr.score_range
                WHEN '90-100' THEN 1
                WHEN '80-89' THEN 2
                WHEN '70-79' THEN 3
                WHEN '60-69' THEN 4
                WHEN '60以下' THEN 5
            END;
            
    ELSIF v_type = 'submission_trend' THEN
        -- 提交趋势
        RETURN QUERY
        WITH teacher_classes AS (
            SELECT DISTINCT uc.class_id
            FROM public.ak_user_classes uc
            WHERE uc.user_id = v_teacher_id AND uc.role = 'teacher'
        ),
        date_series AS (
            SELECT generate_series(v_start_date, v_end_date, '1 day'::interval)::date as date_key
        )
        SELECT 
            ds.date_key,
            COUNT(asub.id)::numeric as value,
            '提交数量' as label,
            COUNT(asub.id)::integer as count
        FROM date_series ds
        LEFT JOIN public.ak_assignment_submissions asub ON ds.date_key = asub.submit_time::date
        LEFT JOIN public.ak_assignments a ON asub.assignment_id = a.id
        LEFT JOIN teacher_classes tc ON a.class_id = tc.class_id
        WHERE tc.class_id IS NOT NULL OR asub.id IS NULL
        GROUP BY ds.date_key
        ORDER BY ds.date_key;
        
    ELSE
        -- 默认返回空结果
        RETURN;
    END IF;
END;
$$;

-- 为函数添加注释
COMMENT ON FUNCTION public.get_chart_data IS '获取图表数据：支持完成率趋势、成绩分布、提交趋势等类型';

-- 4. 获取近期活动数据 (get_recent_activities) - 额外的辅助函数
CREATE OR REPLACE FUNCTION public.get_recent_activities(
    p_teacher_id uuid DEFAULT NULL,
    p_limit integer DEFAULT 20
)
RETURNS TABLE(
    activity_id uuid,
    activity_type text,
    title text,
    description text,
    student_name text,
    assignment_title text,
    activity_time timestamp with time zone,
    time_ago text
) 
LANGUAGE plpgsql 
SECURITY DEFINER
AS $$
DECLARE
    v_teacher_id uuid;
    v_limit integer;
BEGIN
    -- 参数处理
    v_teacher_id := COALESCE(p_teacher_id, auth.uid());
    v_limit := COALESCE(p_limit, 20);
    
    -- 确保是教师用户
    IF NOT EXISTS (
        SELECT 1 FROM public.ak_users 
        WHERE id = v_teacher_id AND role = 'teacher'
    ) THEN
        RAISE EXCEPTION '用户不是教师或不存在';
    END IF;

    RETURN QUERY
    WITH teacher_classes AS (
        SELECT DISTINCT uc.class_id
        FROM public.ak_user_classes uc
        WHERE uc.user_id = v_teacher_id AND uc.role = 'teacher'
    ),
    recent_submissions AS (
        SELECT 
            asub.id as activity_id,
            'assignment_submitted' as activity_type,
            u.username || '提交了作业：' || a.title as title,
            COALESCE(LEFT(asub.content_md, 100), '无描述') as description,
            u.username as student_name,
            a.title as assignment_title,
            asub.submit_time as activity_time
        FROM public.ak_assignment_submissions asub
        INNER JOIN public.ak_assignments a ON asub.assignment_id = a.id
        INNER JOIN public.ak_users u ON asub.student_id = u.id
        INNER JOIN teacher_classes tc ON a.class_id = tc.class_id
        WHERE asub.submit_time >= CURRENT_DATE - INTERVAL '7 days'
    ),
    recent_assignments AS (
        SELECT 
            a.id as activity_id,
            'assignment_created' as activity_type,
            '创建了新作业：' || a.title as title,
            COALESCE(LEFT(a.description, 100), '无描述') as description,
            '系统' as student_name,
            a.title as assignment_title,
            a.created_at as activity_time
        FROM public.ak_assignments a
        INNER JOIN teacher_classes tc ON a.class_id = tc.class_id
        WHERE a.created_at >= CURRENT_DATE - INTERVAL '7 days'
        AND a.teacher_id = v_teacher_id
    ),
    all_activities AS (
        SELECT * FROM recent_submissions
        UNION ALL
        SELECT * FROM recent_assignments
    )
    SELECT 
        aa.activity_id,
        aa.activity_type,
        aa.title,
        aa.description,
        aa.student_name,
        aa.assignment_title,
        aa.activity_time,
        CASE 
            WHEN aa.activity_time > CURRENT_TIMESTAMP - INTERVAL '1 hour' 
            THEN EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - aa.activity_time))::integer / 60 || '分钟前'
            WHEN aa.activity_time > CURRENT_TIMESTAMP - INTERVAL '1 day'
            THEN EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - aa.activity_time))::integer / 3600 || '小时前'
            ELSE EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - aa.activity_time))::integer / 86400 || '天前'
        END as time_ago
    FROM all_activities aa
    ORDER BY aa.activity_time DESC
    LIMIT v_limit;
END;
$$;

-- 为函数添加注释
COMMENT ON FUNCTION public.get_recent_activities IS '获取近期活动：作业提交、新作业创建等';

-- 5. 创建必要的索引以优化查询性能
CREATE INDEX IF NOT EXISTS idx_assignments_teacher_date ON public.ak_assignments(teacher_id, created_at);
CREATE INDEX IF NOT EXISTS idx_assignments_class_due ON public.ak_assignments(class_id, due_date);
CREATE INDEX IF NOT EXISTS idx_submissions_assignment_date ON public.ak_assignment_submissions(assignment_id, submit_time);
CREATE INDEX IF NOT EXISTS idx_submissions_student_score ON public.ak_assignment_submissions(student_id, score) WHERE score IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_user_classes_role ON public.ak_user_classes(user_id, class_id, role);

-- 6. 授权函数给authenticated用户
GRANT EXECUTE ON FUNCTION public.get_teacher_analytics TO authenticated;
GRANT EXECUTE ON FUNCTION public.get_top_performers TO authenticated;
GRANT EXECUTE ON FUNCTION public.get_chart_data TO authenticated;
GRANT EXECUTE ON FUNCTION public.get_recent_activities TO authenticated;

-- 7. 创建RLS策略确保数据安全
-- 这些函数已经在内部进行了权限检查，但我们仍然可以为相关表添加RLS策略

-- 为作业表添加RLS策略（如果还没有的话）
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_policies 
        WHERE tablename = 'ak_assignments' 
        AND policyname = 'teachers_can_manage_own_assignments'
    ) THEN
        CREATE POLICY "teachers_can_manage_own_assignments" ON public.ak_assignments
        FOR ALL TO authenticated
        USING (
            teacher_id = auth.uid() OR
            EXISTS (
                SELECT 1 FROM public.ak_user_classes uc
                WHERE uc.class_id = ak_assignments.class_id
                AND uc.user_id = auth.uid()
                AND uc.role = 'teacher'
            )
        );
    END IF;
END;
$$;

-- 插入示例数据用于测试（可选）
-- INSERT INTO public.ak_languages (code, name, native_name, is_default) VALUES 
-- ('zh-CN', 'Chinese Simplified', '简体中文', true),
-- ('en-US', 'English US', 'English (US)', false)
-- ON CONFLICT (code) DO NOTHING;

-- 创建测试数据的函数
CREATE OR REPLACE FUNCTION public.create_test_analytics_data()
RETURNS void
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
BEGIN
    -- 这个函数可以用来创建一些测试数据
    -- 实际部署时可以删除
    RAISE NOTICE '测试数据创建函数已准备就绪';
END;
$$;

COMMENT ON FUNCTION public.create_test_analytics_data IS '创建分析功能的测试数据（开发用）';
