# SPDX-FileCopyrightText: 2023 Marlon W (Mawoka)
#
# SPDX-License-Identifier: MPL-2.0


import io
import json
import uuid
from datetime import datetime

import bleach
from aiohttp import ClientSession

from classquiz.config import settings, storage, meilisearch, ALLOWED_TAGS_FOR_QUIZ, arq
from classquiz.db.models import Quiz, ABCDQuizAnswer, QuizQuestion, User, StorageItem
from classquiz.kahoot_importer.get import get as get_quiz
from classquiz.helpers import get_meili_data

settings = settings()


async def _download_image(url: str) -> bytes:
    async with ClientSession() as session, session.get(url) as resp:
        return await resp.read()


DEFAULT_COLORS = ["#D6EDC9", "#B07156", "#7F7057", "#4E6E58"]


async def handle_image_upload(url: str, user: User) -> StorageItem:
    image_bytes = await _download_image(url)
    file_obj = StorageItem(
        id=uuid.uuid4(),
        uploaded_at=datetime.now(),
        mime_type="application/octet-stream",
        hash=None,
        user=user,
        size=0,
        deleted_at=None,
        alt_text=None,
        imported=True,
    )
    await file_obj.save()
    await storage.upload(file_name=file_obj.id.hex, file_data=io.BytesIO(image_bytes))
    await arq.enqueue_job("calculate_hash", file_obj.id.hex)
    return file_obj


async def import_quiz(quiz_id: str, user: User) -> Quiz | int:
    """
    Imports a quiz from Kahoot.
    :param user: The user object
    :param quiz_id: The ID of the quiz to import.
    :return: True if the import was successful, False otherwise.
    """
    kahoot_quiz_id = quiz_id
    quiz = await get_quiz(kahoot_quiz_id)
    if type(quiz) is int:
        return quiz
    quiz_questions: list[dict] = []
    new_quiz_id = uuid.uuid4()
    meilisearch.delete_index(settings.meilisearch_index)
    meilisearch.create_index(settings.meilisearch_index)
    uploaded_images: list[StorageItem] = []

    for q in quiz.kahoot.questions:
        answers: list[ABCDQuizAnswer] = []
        image = None
        if q.image is not None and q.image != "":
            image_obj = await handle_image_upload(q.image, user)
            uploaded_images.append(image_obj)
            image = image_obj.id.hex
        for i, a in enumerate(q.choices):
            answers.append(
                (
                    ABCDQuizAnswer(
                        right=a.correct,
                        answer=bleach.clean(a.answer, tags=[], strip=True),
                        color=DEFAULT_COLORS[i],
                    )
                )
            )

        quiz_questions.append(
            QuizQuestion(
                question=bleach.clean(q.question, tags=ALLOWED_TAGS_FOR_QUIZ, strip=True),
                answers=answers,
                time=str(q.time / 1000),
                image=image,
            ).model_dump()
        )
    cover = None
    if quiz.kahoot.cover != "" and quiz.kahoot.cover is not None:
        img_obj = await handle_image_upload(quiz.kahoot.cover, user)
        uploaded_images.append(img_obj)
        cover = img_obj.id.hex
    if quiz.kahoot.description is None or quiz.kahoot.description == "":
        quiz.kahoot.description = "Description Missing!"
    quiz_data = Quiz(
        id=new_quiz_id,
        public=False,
        title=bleach.clean(quiz.kahoot.title, tags=ALLOWED_TAGS_FOR_QUIZ, strip=True),
        description=bleach.clean(quiz.kahoot.description, tags=ALLOWED_TAGS_FOR_QUIZ, strip=True),
        created_at=datetime.now(),
        updated_at=datetime.now(),
        user_id=user.id,
        questions=json.dumps(quiz_questions),
        imported_from_kahoot=True,
        cover_image=cover,
        kahoot_id=uuid.UUID(kahoot_quiz_id),
    )
    meilisearch.index(settings.meilisearch_index).add_documents([await get_meili_data(quiz_data)])
    await quiz_data.save()
    for img in uploaded_images:
        await quiz_data.storageitems.add(img)
    return quiz_data
