import response from "../../response.js";
import models from "../../models/index.js";

export const getStdExercises = async (req, res) => {
  try {
    const stdExercise = await models.StdExercise.findAll();
    response(200, stdExercise, "Success", res);
  } catch (error) {
    console.log(error);
    response(500, null, "Error retrieving student exercise data!", res);
  }
};

export const getStdExerciseById = async (req, res) => {
  try {
    const { id } = req.params;
    const stdExercise = await models.StdExercise.findByPk(id);

    if (!stdExercise) {
      return response(404, null, "Student exercise data not found", res);
    }

    response(200, stdExercise, "Success", res);
  } catch (error) {
    console.log(error);
    res.status(500).json({ message: "Internal Server Error" });
  }
};

export const stdAnswerExercise = async (req, res, next) => {
  try {
    const { answers } = req.body;

    if (!Array.isArray(answers) || answers.length === 0) {
      return response(400, null, "Answers array is required", res);
    }

    for (const answer of answers) {
      const { ID_STUDENT_LEARNING, ID_ADMIN_EXERCISE, ANSWER_STUDENT } = answer;

      if (!ID_STUDENT_LEARNING) {
        return response(400, null, "Id student learning is required", res);
      }

      const existingStdLearning = await models.StdLearning.findByPk(
        ID_STUDENT_LEARNING
      );
      if (!existingStdLearning) {
        return response(404, null, "Id student learning not found", res);
      }

      if (!ID_ADMIN_EXERCISE) {
        return response(400, null, "Id exercise is required", res);
      }

      const exercise = await models.Exercise.findOne({
        where: {
          ID_ADMIN_EXERCISE: ID_ADMIN_EXERCISE,
          ID_LEVEL: existingStdLearning.ID_LEVEL,
        },
      });
      if (!exercise) {
        return response(404, null, "Exercise not found in this level", res);
      }

      if (!ANSWER_STUDENT) {
        return response(400, null, "Answer is required", res);
      }

      const existingStdExercise = await models.StdExercise.findOne({
        where: {
          ID_STUDENT_LEARNING: ID_STUDENT_LEARNING,
          ID_ADMIN_EXERCISE: ID_ADMIN_EXERCISE,
        },
      });

      if (existingStdExercise) {
        existingStdExercise.ANSWER_STUDENT = ANSWER_STUDENT;
        await existingStdExercise.save();
      } else {
        await models.StdExercise.create({
          ID_STUDENT_LEARNING,
          ID_ADMIN_EXERCISE,
          ANSWER_STUDENT,
        });
      }
    }

    req.params.id = answers[0].ID_STUDENT_LEARNING;
    next();
  } catch (error) {
    console.log(error);
    return response(
      500,
      null,
      "Error creating or updating student exercise data!",
      res
    );
  }
};

export const getStudentAnswersByStdLearningId = async (req, res) => {
  try {
    const { id } = req.params;

    const stdLearning = await models.StdLearning.findByPk(id, {
      include: [
        {
          model: models.Level,
          as: "level",
          attributes: ["ID_LEVEL", "NAME_LEVEL"],
          include: [
            {
              model: models.Topic,
              as: "levelTopic",
              attributes: ["ID_TOPIC", "NAME_TOPIC"],
              include: [
                {
                  model: models.Section,
                  as: "topicSection",
                  attributes: ["ID_SECTION", "NAME_SECTION"],
                },
              ],
            },
          ],
        },
        {
          model: models.StdExercise,
          as: "stdExercises",
          include: [
            {
              model: models.Exercise,
              as: "stdExerciseExercises",
              attributes: [
                "ID_ADMIN_EXERCISE",
                "TITLE",
                "QUESTION",
                "QUESTION_TYPE",
                "SCORE_WEIGHT",
                "IMAGE",
                "AUDIO",
                "VIDEO",
              ],
              include: [
                {
                  model: models.MultipleChoices,
                  as: "multipleChoices",
                  attributes: [
                    "OPTION_A",
                    "OPTION_B",
                    "OPTION_C",
                    "OPTION_D",
                    "OPTION_E",
                  ],
                },
                {
                  model: models.MatchingPairs,
                  as: "matchingPairs",
                  attributes: ["LEFT_PAIR", "RIGHT_PAIR"],
                },
              ],
            },
          ],
          attributes: [
            "ID_STUDENT_EXERCISE",
            "ANSWER_STUDENT",
            "IS_CORRECT",
            "RESULT_SCORE_STUDENT",
          ],
        },
      ],
      attributes: ["ID_STUDENT_LEARNING", "ID_LEVEL", "SCORE", "IS_PASS"],
    });

    if (!stdLearning) {
      return response(404, null, "Student learning data not found", res);
    }

    const stdLearningData = stdLearning.toJSON();

    const { NAME_SECTION } = stdLearningData.level.levelTopic.topicSection;
    const { NAME_TOPIC } = stdLearningData.level.levelTopic;
    const { NAME_LEVEL } = stdLearningData.level;

    const sortedExercises = stdLearningData.stdExercises.sort((a, b) => {
      const titleA = a.stdExerciseExercises.TITLE.toUpperCase();
      const titleB = b.stdExerciseExercises.TITLE.toUpperCase();

      return titleA.localeCompare(titleB);
    });

    const mappedExercises = sortedExercises.map((exercise) => {
      const exerciseData = { ...exercise };
      const exerciseDetails = exercise.stdExerciseExercises;
      const questionType = exerciseDetails.QUESTION_TYPE;

      const formattedExercise = {
        ID_STUDENT_EXERCISE: exerciseData.ID_STUDENT_EXERCISE,
        ID_ADMIN_EXERCISE: exerciseDetails.ID_ADMIN_EXERCISE,
        TITLE: exerciseDetails.TITLE,
        QUESTION: exerciseDetails.QUESTION,
        QUESTION_TYPE: exerciseDetails.QUESTION_TYPE,
        SCORE_WEIGHT: exerciseDetails.SCORE_WEIGHT,
        IMAGE: exerciseDetails.IMAGE,
        VIDEO: exerciseDetails.VIDEO,
        AUDIO: exerciseDetails.AUDIO,
        ANSWER_STUDENT: exercise.ANSWER_STUDENT,
        IS_CORRECT: exercise.IS_CORRECT,
        RESULT_SCORE_STUDENT: exercise.RESULT_SCORE_STUDENT,
      };

      if (questionType === "MCQ") {
        formattedExercise.multipleChoices = exerciseDetails.multipleChoices;
      } else if (questionType === "MPQ") {
        formattedExercise.matchingPairs = exerciseDetails.matchingPairs;
      }

      return formattedExercise;
    });

    return response(
      200,
      {
        ID_STUDENT_LEARNING: stdLearningData.ID_STUDENT_LEARNING,
        ID_LEVEL: stdLearningData.ID_LEVEL,
        NAME_SECTION,
        NAME_TOPIC,
        NAME_LEVEL,
        SCORE: stdLearningData.SCORE,
        IS_PASS: stdLearningData.IS_PASS,
        stdExercises: mappedExercises,
      },
      "Student learning exercises retrieved successfully",
      res
    );
  } catch (error) {
    console.error(error);
    return response(
      500,
      null,
      "Error retrieving student learning exercises",
      res
    );
  }
};
