package com.seer.teach.admin.util;

import cn.hutool.core.collection.CollectionUtil;
import com.seer.teach.admin.request.GenerateTaskReq;
import com.seer.teach.admin.request.KnowledgePointSplitReq;
import com.seer.teach.common.enums.ExampleQuestionTypesEnum;
import com.seer.teach.teacher.module.entity.ExampleQuestionsEntity;
import com.seer.teach.teacher.module.entity.KnowSummaryEntity;
import com.seer.teach.teacher.module.entity.KnowledgePointEntity;
import com.seer.teach.teacher.module.entity.TeachGoalsEntity;
import com.seer.teach.teacher.module.entity.TeachMethodsEntity;
import com.seer.teach.teacher.module.entity.TeachTextsEntity;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

@Slf4j
public class PromptBuilder {

    /**
     * 构建用于生成示例题目的提示词
     *
     * @param exampleQuestion 示例题目
     * @param knowledgePoint  知识点
     * @param count           生成数量
     * @return 提示词
     */
    public static String buildPromptForQuestionGeneration(ExampleQuestionsEntity exampleQuestion,
                                                          KnowledgePointEntity knowledgePoint,
                                                          Integer count) {
        String optionsPart = ExampleQuestionTypesEnum.CHOICE.getCode().equals(exampleQuestion.getType()) ?
            "   - options: 选项数组（仅选择题需要，每个选项包含content和sort字段）\n\n" : "";

        return """
                你是一个教学题目的专家，请根据以下示例题目生成%d道类似的题目。
                
                知识点：%s
                知识点总结：%s
                
                要求：
                1. 题目必须基于相同的教学知识点
                2. 题目难度应与示例题目相当
                3. 题型必须与示例题目一致
                4. 答案必须明确且唯一
                5. 提供详细的解题过程或解析
                6. 返回严格的JSON数组格式，每项包含以下字段：
                   - question: 题干内容
                   - answer: 答案内容
                   - solution: 解析内容
                %s
                输出格式示例：
                [
                  {
                    "question": "题目内容",
                    "answer": "答案内容",
                    "solution": "解析内容",
                    %s
                  }
                ]
                """.formatted(count, knowledgePoint.getKnowledgePointName(), knowledgePoint.getSummary(), optionsPart,
            ExampleQuestionTypesEnum.CHOICE.getCode().equals(exampleQuestion.getType()) ?
                "\"options\": [\n         {\"content\": \"选项A内容\", \"sort\": 1},\n        {\"content\": \"选项B内容\", \"sort\": 2}\n      ]" : "");
    }

    /**
     * 构建生成题库题目的提示词
     *
     * @param knowledgePoints  知识点信息
     * @param count            生成数量
     * @param req              请求参数
     * @return 提示词
     */
    public static String buildPromptForBankQuestionGeneration(KnowledgePointEntity knowledgePoints, Integer count, GenerateTaskReq req) {
        // 判断是否是一、二年级的数学题目
        boolean isLowerElementaryMath = isLowerElementaryMath(req.getGradeIds(), req.getSubjectId());
        
        // 判断是否是三、四年级的英语题目
        boolean isMiddleElementaryEnglish = isMiddleElementaryEnglish(req.getGradeIds(), req.getSubjectId());

        String latexRequirement = isNeedLatex(req.getSubjectId()) ? "  10. 输出的题目内容,答案，解析，其中涉及到公式的，请使用Latex\n\n" : "";
        
        String englishRequirement = isMiddleElementaryEnglish ? "  10. 这是三四年级的英语题目，请尽量使用中文出题，题目内容和选项中涉及的英语内容应适合该年龄段学生理解\n\n" : "";
        
        String lowerElementaryMathNote = isLowerElementaryMath ? "\n特别注意：这是一、二年级的题目，请尽量以图文并茂的形式展示题目内容和选项，使题目更适合低年级学生理解。\n" : "";
        
        String middleElementaryEnglishNote = isMiddleElementaryEnglish ? "\n特别注意：这是三、四年级的英语题目，请尽量使用中文出题，让题目更容易被学生理解。\n" : "";
        
        String mathRequirements = "";
        if (req.getSubjectId() == 2) { // 数学学科
            mathRequirements = "\n数学题目解析(solution字段)规范要求：\n";
            if(Objects.nonNull(req.getGradeId())){
                // 初中三个年级的要求
                if (req.getGradeId() == 7) { // 七年级(初一)
                    mathRequirements += "七年级(初一)解析标准：\n";
                    mathRequirements += "- 格式要求：从算术思维向代数思维过渡，强调基本概念、运算规则和解题格式的建立\n";
                    mathRequirements += "- 解析步骤：读与标(阅读题目，标记关键数据) -> 联与析(联想相关数学概念) -> 算或解(执行计算或按步骤解方程) -> 验与答(初步检验答案，并规范作答)\n";
                    mathRequirements += "- 示例题型：代数方程应用题，要求严格按照\"设->列->解->验->答\"的格式进行解答\n";
                }

                if (req.getGradeId() == 8) { // 八年级(初二)
                    mathRequirements += "八年级(初二)解析标准：\n";
                    mathRequirements += "- 格式要求：逻辑推理能力要求提高，几何证明和函数概念引入，解题需展现严密的因果链条\n";
                    mathRequirements += "- 解析步骤：条件梳理(明确已知条件) -> 目标分析(明确待证明结论) -> 思路探寻(寻找定理、公式) -> 逻辑推演(清晰展示推理) -> 结论总结(给出最终结论)\n";
                    mathRequirements += "- 示例题型：几何证明题，要求严格按照\"已知->求证->证明\"的格式进行解答\n";
                }

                if (req.getGradeId() == 9) { // 九年级(初三)
                    mathRequirements += "九年级(初三)解析标准：\n";
                    mathRequirements += "- 格式要求：知识高度综合，强调数学思想方法(分类讨论、数形结合、转化与化归、方程思想、模型思想)的应用，解法灵活多样\n";
                    mathRequirements += "- 解析步骤：审题与建模(识别问题本质) -> 思路选择与规划(选择合适解题路径) -> 执行与讨论(计算或推理，必要时分类讨论) -> 检验与反思(检验答案合理性)\n";
                    mathRequirements += "- 示例题型：二次函数综合题，要求体现数学思想方法的灵活应用\n";
                }
            }
        }
        
        return """
                你是一位资深的'%s'教学专家，请根据以下知识点和示例题目为每一类型(1单选选择题 2多选选择题 4判断题 6填空题)的题目分别生成%d道类似的题目。
                
                知识点名称：%s
                知识点总结：%s
                对应的年级：%s
                对应的学科：%s
                
                要求：
                   1. 题目必须基于"%s"这个知识点,不能超出对应年纪和学生的理解范围
                   2. 题目难度应在1.00和5.00范围内，小数点后面两位小数，1.00为最简单，5.00为最难，且每道题的难度不能相同
                   3. 答案必须明确且唯一
                   4. 提供详细的解析过程,如果是数学，物理，化学，必须列出具体的解题步骤
                   5. 题干内容不能包含题目类型，如 （对/错）,（多选）
                   6. 如果是选择题(单选选择题或则多选选择题)，题干内容不能包含选项，如(题目内容，选项A内容，选项B内容)
                   7. 如果是判断题,答案(answer)只能是‘对’和‘错’，如果是选择题，答案只能是选项A,B,C,D,E... 
                   8. 每一类型题目的数量必须是%d，不能省略,如要求输出10道题目，不能只输出9道题目
                   9. 输出的格式必须是json格式，字段如下：
                         - title:  题干内容
                         - answer: 答案内容
                         - solution: 解析内容，提供详细的解析过程,如果是数学,物理或则化学的，必须列出具体的解题步骤。如果是英语，尽量使用中文
                         - type: 题型（1->单选选择题, 2->多选选择题,  4->判断题,  6->填空题）
                         - difficulty: 题目难易度系数（1-5的整数，5为最难，每道题难度不能相同）
                         - isNeedImage: 是否需要图片（0->不需要, 1->需要），如果是以图片的形式展示题目内容或者选项，则为1，否则为0
                         - options: 选择题选项数组（仅题型为单选选择题或则多选选择题需要，每个选项包含content和sort字段,选项内容不能一样）
                %s%s
                输出格式示例：
                [
                  {
                    "title": "题目内容",
                    "answer": "答案内容",
                    "solution": "解析内容",
                    "isNeedImage": "0",
                    "type": 1,
                    "difficulty": 3.34,
                    "options": [
                      {"content": "A. 选项A内容", "sort": 1},
                      {"content": "B. 选项B内容", "sort": 2},
                      {"content": "C. 选项C内容", "sort": 3},
                      {"content": "D. 选项D内容", "sort": 4}
                    ]
                  }
                ]
                
                %s%s%s
                """.formatted(
            getGradeTypeName(req.getGradeType()),
            count,
            knowledgePoints.getKnowledgePointName(),
            req.getSummary(),
            getGradeNameList(req.getGradeIds()),
            getSubjectName(req.getSubjectId()),
            knowledgePoints.getKnowledgePointName(),
            count,
            latexRequirement,
            englishRequirement,
            lowerElementaryMathNote,
            middleElementaryEnglishNote,
            mathRequirements
        );
    }

    /**
     * 构建知识点拆分提示词
     *
     * @param knowledgePoint 知识点实体
     * @return 提示词
     */
    public static String buildSplitPrompt(KnowledgePointEntity knowledgePoint, KnowSummaryEntity summary, KnowledgePointSplitReq req) {
        String specificNames = "";
        if (CollectionUtil.isNotEmpty(req.getKnowledgePointNames())) {
            StringBuilder namesBuilder = new StringBuilder();
            for (int i = 0; i < req.getKnowledgePointNames().size(); i++) {
                namesBuilder.append("  ").append(i + 1).append(". ").append(req.getKnowledgePointNames().get(i)).append("\n");
            }
            specificNames = "要求拆分为以下名称的知识点：\n" + namesBuilder.toString();
        }

        String requirements = CollectionUtil.isNotEmpty(req.getKnowledgePointNames()) ?
            String.format("1. 将原始知识点拆分为上面指定的%d个名称的知识点，每个知识点需要包含以下信息：\n", req.getCount()) :
            String.format("1. 将原始知识点拆分为%d个更具体、更细粒度的知识点，每个知识点需要包含以下信息：\n", req.getCount());

        return """
                你是一位资深的教学专家，请根据以下知识点进行拆分，将其拆分为%d个更细粒度的知识点。
                
                原始知识点名称：%s
                原始知识点总结：%s
                对应的年级：%s
                对应的学科：%s
                %s
                要求：
                %s
                   - knowledgePointName: 拆分后的知识点名称
                   - summary: 知识点的简要总结
                   - exampleQuestions: 该知识点的示例题目列表
                2. 每个知识点不能超出对应年纪和学生的理解范围
                3. 知识点总结必须符合教学逻辑（能直接被教师用于教学视频脚本），应包括：①基本定义；②在学科体系中的地位与作用；③与前后知识的衔接关系；④学习意义与实际应用；⑤常见误区与误解。少于 300 字。
                4. exampleQuestions字段要求：
                   - 每个题目包含type(题型)、question(题目内容)、options(选项，仅选择题需要)、answer(答案)、explanation(解析)字段
                   - 题型包括：包含4种题型(1单选选择题 2多选选择题 4判断题 6填空题)
                   - 每种题型1道题目
                
                
                5. 返回严格的JSON数组格式，示例如下：
                [
                  {
                    "knowledgePointName": "拆分后的知识点名称",
                    "summary": "知识点总结",
                    "exampleQuestions": [
                      {
                        "type": "1",
                        "question": "题目内容",
                        "options": [
                             {"content": "A. 选项A内容", "sort": 1},
                             {"content": "B. 选项B内容", "sort": 2},
                             {"content": "C. 选项C内容", "sort": 3},
                             {"content": "D. 选项D内容", "sort": 4}
                        ]
                        "answer": "答案",
                        "explanation": "解析内容"
                      }
                    ]
                  }
                ]
                """.formatted(
            req.getCount(),
            knowledgePoint.getKnowledgePointName(),
            summary.getSummary(),
            getGradeNameList(req.getGradeIds()),
            getSubjectName(knowledgePoint.getSubjectId()),
            specificNames,
            requirements
        );
    }


    /**
     * 构建知识点检查提示词
     *
     * @param knowledgePoint 知识点实体
     * @param summary        知识点摘要
     * @return 提示词
     */
    public static String buildCheckPrompt(KnowledgePointEntity knowledgePoint, KnowSummaryEntity summary, Collection<Integer> gradeIds) {
        return """
                你是一位资深的教学专家，请根据以下知识点判断其内容是否正确和超纲。
                
                知识点名称：%s
                知识点总结：%s
                对应的年级：%s
                对应的学科：%s
                
                
                请判断以下内容：
                1. 该知识点内容是否正确
                2. 该知识点是否超出指定年级学生的学习范围（超纲）
                3. 如果超纲，请说明超纲原因，并给出适合的替换知识点名称和总结
                4. 请提供该知识点的示例题目
                
                
                要求：
                1. 返回严格的JSON格式，包含以下字段：
                   - isCorrect: 知识点内容是否正确 (boolean)
                   - isOutOfScope: 是否超纲 (boolean)
                   - outOfScopeReason: 超纲原因 (string, 如果没有超纲则为null)
                   - suggestedKnowledgePointName: 建议的知识点名称 (string, 如果没有超纲则为null)
                   - suggestedSummary: 建议的知识点总结 (string, 如果没有超纲则为null)
                   - exampleQuestions: 示例题目列表 (array)
                2. exampleQuestions字段要求：
                   - 每个题目包含type(题型)、question(题目内容)、options(选项，仅选择题需要)、answer(答案)、explanation(解析)字段
                   - 题型包括：包含4种题型(1单选选择题 2多选选择题 4判断题 6填空题)
                   - 每种题型1道题目
                
                
                输出格式示例：
                {
                  "isCorrect": true,
                  "isOutOfScope": false,
                  "outOfScopeReason": null,
                  "suggestedKnowledgePointName": null,
                  "suggestedSummary": null,
                  "exampleQuestions": [
                    {
                      "type": "1",
                      "question": "题目内容",
                      "options": ["选项A", "选项B", "选项C", "选项D"],
                      "answer": "答案",
                      "explanation": "解析内容"
                    }
                  ]
                }
                """.formatted(
            knowledgePoint.getKnowledgePointName(),
            summary != null ? summary.getSummary() : "",
            getGradeNameList(gradeIds),
            getSubjectName(knowledgePoint.getSubjectId())
        );
    }

    /**
     * 构建讲课稿生成提示词
     *
     * @param teachGoal 教学目标
     * @param req       生成讲课稿请求
     * @return 提示词
     */
    public static String buildPromptForTeachTextGeneration(TeachGoalsEntity teachGoal, List<TeachMethodsEntity> methods, GenerateTaskReq req) {
        StringBuilder methodsBuilder = new StringBuilder();
        for (int i = 0; i < methods.size(); i++) {
            TeachMethodsEntity method = methods.get(i);
            methodsBuilder.append((i + 1)).append(". ").append(method.getName());
            if (method.getDescription() != null && !method.getDescription().isEmpty()) {
                methodsBuilder.append(": ").append(method.getDescription());
            }
            methodsBuilder.append("(methodId: ").append(method.getId()).append(")\n");
        }

        return """
                你是一位经验丰富的教师，请根据以下教学目标和教学重点，针对每种教学方法分别生成一份详细且有针对性的讲课稿。
                
                教学目标: %s
                教学重点: %s
                %s%s
                教学方法列表:
                %s
                
                请根据以上教学目标、重点和教学方法生成详细的讲课稿，要求如下:
                1. 内容详实，语言生动，适合课堂讲解
                2. 结构清晰，逻辑性强
                3. 包含导入、新授、巩固练习、小结等教学环节
                4. 每种教学方法都需要生成对应的讲课稿
                5. 字数不少于800字
                6. 以JSON数组格式输出，每个元素包含sort(排序)、methodId(教学方法Id)和text(讲课稿内容)、isDefault(是否默认，1：是，0：否)，videoContent(讲课稿内容对应的视频内容)字段
                
                
                示例输出格式:
                [
                  {
                    "sort": 1,
                    "methodId": 385,
                    "isDefault": 1,
                    "text": "这里是针对第一种教学方法的讲课稿内容...",
                    "videoContent": "针对第一种教学方法的讲课稿内容对应的视频内容...",
                  },
                  {
                    "sort": 2,
                    "methodId": 386,
                    "isDefault": 0,
                    "text": "这里是针对第二种教学方法的讲课稿内容...",
                    "videoContent": "针对第二种教学方法的讲课稿内容对应的视频内容...",
                  }
                  {
                    "sort": 3,
                    "isDefault": 0,
                    "methodId": 387,
                    "text": "这里是针对第三种教学方法的讲课稿内容...",
                    "videoContent": "针对第三种教学方法的讲课稿内容对应的视频内容...",
                  }
                ]
                """.formatted(
            teachGoal.getGoal(),
            teachGoal.getPoint(),
            Objects.nonNull(req.getGradeIds()) ? "对应的年级：" + getGradeName(req.getGradeId()) + "\n" : "",
            Objects.nonNull(req.getSubjectId()) ? "对应的学科：" + getSubjectName(req.getSubjectId()) + "\n\n" : "",
            methodsBuilder.toString()
        );
    }

    public static String buildPromptForTeachGoalGeneration(KnowledgePointEntity knowledgePoint, Integer count, GenerateTaskReq req) {
        return """
                你是一位资深的'%s'教学专家，请根据以下知识点生成%d个教学目标（考点）。
                
                知识点名称：%s
                知识点总结：%s
                对应的年级：%s
                对应的学科：%s
                
                
                要求：
                   1. 教学目标必须基于"%s"这个知识点
                   2. 教学目标应适合对应年级的学生理解和掌握
                   3. 每个教学目标应包含具体的学习成果描述
                   4. 提供对应的教学重点
                   5. 可以提供推荐的视频教学链接（可选）
                   6. 每个教学目标需要有一个排序编号
                   7. 输出的格式必须是json格式，字段如下：
                         - goal: 教学目标内容
                         - point: 教学重点
                         - sort: 排序编号
                
                
                输出格式示例：
                [
                  {
                    "goal": "教学目标内容",
                    "point": "教学重点",
                    "sort": 1,
                  }
                ]
                """.formatted(
            getGradeTypeName(req.getGradeType()),
            count,
            knowledgePoint.getKnowledgePointName(),
            req.getSummary(),
            getGradeNameList(req.getGradeIds()),
            getSubjectName(req.getSubjectId()),
            knowledgePoint.getKnowledgePointName()
        );
    }

    /**
     * 构建提示词
     *
     * @param text 讲课稿实体
     * @return 提示词
     */
    public static String buildPromptForTeachTextVideoScriptGeneration(TeachTextsEntity text) {
        return """
                请根据以下视频内容描述，生成一个完整的Python脚本，该脚本能够直接生成高质量的教学视频。
                
                ## 视频内容描述:
                %s
                
                
                ## 核心要求:
                1. **视频类型**: 生成的是纯视觉教学视频，不需要包含任何字幕或音频
                2. **视频质量**: 必须是高质量的视觉呈现，包括清晰的图形、动画和视觉效果
                3. **教学重点**: 通过视觉元素（图表、动画、代码演示、视觉示例等）清晰地传达教学内容
                
                
                ## Python代码要求:
                
                ### 1. 代码结构:
                - 必须是完整的、可直接运行的独立脚本
                - 包含所有必要的导入语句和依赖
                - 包含主程序入口，可直接执行生成视频
                
                
                ### 2. 视觉生成要求:
                - **使用专业的视觉库**: 如Matplotlib, Plotly, Seaborn, MoviePy, OpenCV, PIL等
                - **高质量视觉效果**:
                  - 清晰美观的图表和可视化
                  - 流畅的动画和过渡效果
                  - 合适的颜色搭配和视觉层次
                  - 适当的文本标注（作为图形的一部分，而非字幕）
                - **视觉叙事**: 通过视觉序列清晰地展示概念演变或步骤流程
                
                
                ### 3. 代码质量:
                - **完整注释**:
                  - 文件头部：说明视频主题、主要视觉元素和依赖
                  - 函数/类：详细说明功能和参数
                  - 关键步骤：解释视觉生成逻辑
                - **错误处理**: 包含适当的异常处理和边界情况
                - **模块化设计**: 将不同功能封装为函数或类
                
                
                ### 4. 依赖管理:
                - 在文件开头通过注释明确列出所有第三方库
                - 提供pip安装命令的注释
                
                
                ### 5. 特别注意事项:
                - **不要生成音频处理代码**（如声音添加、音轨处理）
                - **不要生成字幕相关代码**（如字幕叠加、文本时间轴）
                - **专注于视觉表达**：通过图形、动画、图表等视觉元素传达信息
                - **视频时长**：根据内容复杂度，生成合理时长的视频（通常在1-5分钟）
                
                
                ## 输出格式:
                严格按以下JSON格式输出，不要包含任何解释或额外文本：
                [
                  {
                    "pythonScript": "完整的Python脚本代码，可直接运行生成高质量无字幕无音频的教学视频"
                  }
                ]
                
                
                ## 示例思考方向（根据具体内容调整）:
                - 如果是编程教学：生成代码执行过程的可视化动画
                - 如果是数学教学：生成公式推导的逐步动画演示
                - 如果是数据科学：生成数据处理流程的可视化
                - 如果是算法教学：生成算法步骤的动态演示
                - 如果是概念讲解：生成概念演变的分步图示
                """.formatted(text.getVideoContent());
    }

    private static boolean isNeedLatex(Integer subjectId) {
        return subjectId == 2 || subjectId == 10 || subjectId == 11;
    }


    /**
     * 获取题型文本描述
     *
     * @param type 题型编码
     * @return 题型描述
     */
    private static String getQuestionTypeText(Integer type) {
        return switch (type) {
            case 1 -> "选择题";
            case 2 -> "多选选择题";
            case 3 -> "问答题";
            case 4 -> "判断题";
            case 5 -> "计算题";
            case 6 -> "填空题";
            default -> "其他题型";
        };
    }

    private static String getGradeTypeName(Integer gradeType) {
        return switch (gradeType) {
            case 1 -> "小学";
            case 2 -> "初中";
            case 3 -> "高中";
            default -> throw new RuntimeException("未知的学段类型");
        };
    }

    private static String getSubjectName(Integer subjectId) {
        return switch (subjectId) {
            case 1 -> "语文";
            case 2 -> "数学";
            case 3 -> "英语";
            case 4 -> "品德与生活";
            case 5 -> "科学";
            case 6 -> "历史";
            case 7 -> "地理";
            case 8 -> "生物学";
            case 9 -> "政治";
            case 10 -> "物理";
            case 11 -> "化学";
            default -> throw new RuntimeException("未知的学科类型");
        };
    }

    private static String getGradeName(Integer gradeId) {
        return switch (gradeId) {
            case 1 -> "一年级";
            case 2 -> "二年级";
            case 3 -> "三年级";
            case 4 -> "四年级";
            case 5 -> "五年级";
            case 6 -> "六年级";
            case 7 -> "初一";
            case 8 -> "初二";
            case 9 -> "初三";
            case 10 -> "高中";
            default -> throw new RuntimeException("未知的学科类型");
        };
    }

    private static String getGradeNameList(Collection<Integer> gradeIds) {
        List<String> gradeNames = new ArrayList<>();
        for (Integer gradeId : gradeIds) {
            gradeNames.add(getGradeName(gradeId));
        }
        return String.join(",", gradeNames);
    }

    /**
     * 判断是否是小学一、二年级的数学题目
     *
     * @param gradeIds  年级IDs
     * @param subjectId 学科ID
     * @return 是否是小学一、二年级的数学题目
     */
    private static boolean isLowerElementaryMath(Collection<Integer> gradeIds, Integer subjectId) {
        // 判断是否为数学学科（ID为2）
        if (subjectId == null || subjectId != 2) {
            return false;
        }

        // 判断是否为小学一、二年级（ID为1或2）
        if (CollectionUtil.isNotEmpty(gradeIds)) {
            for (Integer gradeId : gradeIds) {
                if (gradeId == 1 || gradeId == 2) {
                    return true;
                }
            }
        }

        return false;
    }
    
    /**
     * 判断是否是小学三、四年级的英语题目
     *
     * @param gradeIds  年级IDs
     * @param subjectId 学科ID
     * @return 是否是小学三、四年级的英语题目
     */
    private static boolean isMiddleElementaryEnglish(Collection<Integer> gradeIds, Integer subjectId) {
        // 判断是否为英语学科（ID为3）
        if (subjectId == null || subjectId != 3) {
            return false;
        }

        // 判断是否为小学三、四年级（ID为3或4）
        if (CollectionUtil.isNotEmpty(gradeIds)) {
            for (Integer gradeId : gradeIds) {
                if (gradeId == 3 || gradeId == 4) {
                    return true;
                }
            }
        }

        return false;
    }
}