<template>
    <div v-if="quiz.doc">
        <div class="bg-blue-100 py-2 px-2 mb-4 rounded-md text-sm text-blue-800">
            <div class="leading-relaxed">
                {{ __("This quiz consists of {0} questions.").format(quiz.doc.questions.length) }}
            </div>
            <div v-if="quiz.doc.passing_percentage" class="leading-relaxed">
                {{ __("You will have to get {0}% correct answers in order to pass the quiz.").format(quiz.doc.passing_percentage) }}
            </div>
            <div v-if="quiz.doc.max_attempts" class="leading-relaxed">
                {{ __("You can attempt this quiz {0}.").format(quiz.doc.max_attempts == 1 ? "1 time" : `${quiz.doc.max_attempts} times`) }}
            </div>
            <div v-if="quiz.doc.time" class="leading-relaxed">
                {{ __("The quiz has a time limit.For each question you will be given { 0} seconds.").format(quiz.doc.time) }}
            </div>
        </div>
        <div v-if="activeQuestion == 0">
            <div class="border text-center p-20 rounded-md">
                <div class="font-semibold text-lg">
                    {{ quiz.doc.title }}
                </div>
                <Button v-if="!quiz.doc.max_attempts || attempts.data?.length < quiz.doc.max_attempts" @click="startQuiz" class="mt-2">
                    <span>
                        {{ __("Start") }}
                    </span>
                </Button>
                <div v-else>
                    {{ __("You have already exceeded the maximum number of attempts allowed for this quiz.") }}
                </div>
            </div>
        </div>
        <div v-else-if="!quizSubmission.data">
            <div v-for="(question, qtidx) in quiz.doc.questions">
                <div v-if="qtidx == activeQuestion - 1 && questionDetails.data" class="border rounded-md p-5">
                    <div class="flex justify-between">
                        <div class="text-sm">
                            <span class="mr-2">
                                {{ __("Question {0}").format(activeQuestion) }}:
                            </span>
                            <span>
                            {{ questionDetails.data.multiple ? __("Choose all answers that apply") : __("Choose one answer") }}
                            </span>
                        </div>
                        <div class="text-gray-900 text-sm font-semibold item-left">
                            {{ question.marks }} {{ question.marks == 1 ? __("Mark") : __("Marks") }}
                        </div>
                    </div>
                    <div class="text-gray-900 font-semibold mt-2">
                        {{ questionDetails.data.question }}
                    </div>
                    <div v-if="questionDetails.data.type == 'Choices'" v-for="index in 4">
                        <label v-if="questionDetails.data[`option_${index}`]"
                            class="flex items-center bg-gray-200 rounded-md p-3 mt-4 w-full cursor-pointer focus:border-blue-600">

                                <input v-if="!showAnswers.length && !questionDetails.data.multiple" type="radio" 
                                :name="encodeURIComponent(questionDetails.data.question)"
                                class="w-3.5 h-3.5 text-gray-900 focus:ring-gray-200"
                                @change="markAnswer(index)">

                                <input v-else-if="!showAnswers.length && questionDetails.data.multiple" type="checkbox" 
                                    :name="encodeURIComponent(questionDetails.data.question)"
                                    class="w-3.5 h-3.5 text-gray-900 rounded-sm focus:ring-gray-200"
                                    @change="markAnswer(index)">

                                <div v-else-if="quiz.doc.show_answers" v-for="(answer, idx) in showAnswers">
                                    <div v-if="index - 1 == idx">
                                        <CheckCircle v-if="answer" class="w-4 h-4 text-green-500"/>
                                        <MinusCircle v-else-if="questionDetails.data[`is_correct_${index}`]"
                                        class="w-4 h-4 text-green-500"/>
                                        <XCircle v-else-if="answer == 0" class="w-4 h-4 text-red-500"/>
                                        <MinusCircle v-else class="w-4 h-4"/>
                                    </div>
                                </div>
                                <span class="ml-2">
                                    {{ questionDetails.data[`option_${index}`] }}
                                </span>
                        </label>
                        <div v-if="questionDetails.data[`explanation_${index}`]" class="mt-2 text-sm hidden">
                            {{ questionDetails.data[`explanation_${index}`] }}
                        </div>
                    </div>
                    <div class="flex items-center justify-between mt-8">
                        <div>
                            {{  __("Question {0} of {1}").format(activeQuestion, quiz.doc.questions.length) }}
                        </div>
                        <Button v-if="quiz.doc.show_answers && !showAnswers.length" @click="checkAnswer()">
                            <span>
                                {{ __("Check") }}
                            </span>
                        </Button>
                        <Button v-else-if="activeQuestion != quiz.doc.questions.length" @click="nextQuetion()">
                            <span>
                                {{ __("Next") }}
                            </span>
                        </Button>
                        <Button v-else @click="submitQuiz()">
                            <span>
                                {{ __("Submit") }}
                            </span>
                        </Button>
                    </div>
                </div>
            </div>
        </div>
        <div v-else class="border rounded-md p-20 text-center">
            <div class="text-lg font-semibold">
                {{ __("Quiz Summary") }}
            </div>
            <div>
                {{ __("You got {0}% correct answers with a score of {1} out of {2}").format(Math.ceil(quizSubmission.data.percentage), quizSubmission.data.score, quizSubmission.data.score_out_of) }}
            </div>
            <Button @click="resetQuiz()" class="mt-2"
                v-if="!quiz.doc.max_attempts || attempts?.data.length < quiz.doc.max_attempts">
                <span>
                    {{ __("Try Again") }}
                </span>
            </Button>
        </div>
        <div v-if="quiz.doc.show_submission_history && attempts?.data" class="mt-10">
            <ListView :columns="getSubmissionColumns()" :rows="attempts?.data" row-key="name"
                :options="{selectable: false, showTooltip: false}">
            </ListView>
        </div>
        
    </div>
</template>
<script setup>
import { createDocumentResource, Button, createResource, ListView } from 'frappe-ui';
import { ref, watch, reactive, inject } from 'vue';
import { createToast } from "@/utils/"
import { CheckCircle, XCircle, MinusCircle } from "lucide-vue-next"
import { timeAgo } from "@/utils"
const user = inject("$user");

const activeQuestion = ref(0);
const currentQuestion = ref("");
const selectedOptions = reactive([0,0,0,0]);
const showAnswers = reactive([])

const props = defineProps({
    quizName: {
        type: String,
        required: true,
    },
});

const quiz = createDocumentResource({
    doctype: "LMS Quiz",
    name: props.quizName,
    cache: ["quiz", props.quizName],
    auto: true,
});

const attempts = createResource({
    url: "frappe.client.get_list",
    makeParams(values) {
        return {
            doctype: "LMS Quiz Submission",
            filters: {
                member: user.data?.name,
                quiz: quiz.doc?.name,
            },
            fields: ["name", "creation", "score", "score_out_of", "percentage", "passing_percentage"],
            order_by: "creation desc",
        }
    },
    auto: true,
    transform(data) {
        data.forEach((submission, index) => {
            submission.creation = timeAgo(submission.creation);
            submission.idx = index + 1;
        });
    }
})

const quizSubmission = createResource({
    url: "lms.lms.doctype.lms_quiz.lms_quiz.quiz_summary",
    makeParams(values) {
        return {
            quiz: quiz.doc.name,
            results: localStorage.getItem(quiz.doc.title),
        }
    }
})

const questionDetails = createResource({
    url: "lms.lms.utils.get_question_details",
    makeParams(values) {
        return {
            question: currentQuestion.value,
        }
    }
})

watch(activeQuestion, (value) => {
    if (value > 0) {
        currentQuestion.value = quiz.doc.questions[value - 1].question;
        questionDetails.reload();
    }
})

const startQuiz = () => {
    activeQuestion.value = 1;
    localStorage.removeItem(quiz.doc.title);
}

const markAnswer = (index) => {
    if (!questionDetails.data.multiple)
        selectedOptions.splice(0, selectedOptions.length, ...[0,0,0,0]);
    selectedOptions[index - 1] = selectedOptions[index - 1] ? 0 : 1;
}

const getAnswers = () => {
    let answers = [];
    selectedOptions.forEach((value, index) => {
        if (selectedOptions[index])
            answers.push(questionDetails.data[`option_${index + 1}`])
    });
    return answers;
};

const checkAnswer = () => {
    let answers = getAnswers();
    if (!answers.length) {
        createToast({
            title: "Please select an option",
            icon: 'alert-circle',
            iconClasses: 'text-yellow-600 bg-yellow-100',
        });
        return;
    }

    createResource({
        url: "lms.lms.doctype.lms_quiz.lms_quiz.check_answer",
        params: {
            "question": currentQuestion.value,
            "type": questionDetails.data.type,
            "answers": JSON.stringify(answers)
        },
        auto: true,
        onSuccess(data) {
            selectedOptions.forEach((option, index) => {
                if (option) {
                    showAnswers[index] = option && data[index]
                } else if (questionDetails.data[`is_correct_${index + 1}`]) {
                    showAnswers[index] = 0
                } else {
                    showAnswers[index] = undefined
                }
            });
            addToLocalStorage();
            if (!quiz.doc.show_answers) {
                resetQuestion();
            }
        }
    })
};

const addToLocalStorage = () => {
    let quizData = JSON.parse(localStorage.getItem(quiz.doc.title));
    let questionData = {
        "question_index": activeQuestion.value,
        "answers": getAnswers().join(),
        "is_correct": showAnswers.filter((answer) => {
            return answer != undefined
        })
    }
    quizData ? quizData.push(questionData) : (quizData = [questionData]);
    localStorage.setItem(quiz.doc.title, JSON.stringify(quizData));
}

const nextQuetion = () => {
    if (!quiz.doc.show_answers) {
        checkAnswer();
    } else {
        resetQuestion();
    }
}

const resetQuestion = () => {
    if (activeQuestion.value == quiz.doc.questions.length)
        return;
    activeQuestion.value = activeQuestion.value + 1
    selectedOptions.splice(0, selectedOptions.length, ...[0, 0, 0, 0]);
    showAnswers.length = 0;
}

const submitQuiz = () => {
    if (!quiz.doc.show_answers) {
        checkAnswer();
        setTimeout(() => {
            createSubmission();
        }, 500);
        return;
    }
    createSubmission();
}

const createSubmission = () => {
    quizSubmission.reload().then(() => {
        attempts.reload();
    });
}

const resetQuiz = () => {
    activeQuestion.value = 0;
    selectedOptions.splice(0, selectedOptions.length, ...[0,0,0,0]);
    showAnswers.length = 0;
    quizSubmission.reset();
}

const getSubmissionColumns = () => {
    return [
        {
            label: "No.",
            key: "idx",
            
        },
        {
            label: "Date",
            key: "creation",
        },
        {
            label: "Score",
            key: "score",
            align: "center"
        },
        {
            label: "Score out of",
            key: "score_out_of",
            align: "center"
        },
        {
            label: "Percentage",
            key: "percentage",
            align: "center"
        },
    ]
}
</script>