# Generated by https://quicktype.io

from typing import List, Any, Optional
from .course import TypeEnum

import tomd


class Data:
    id: int
    type: str
    assignment: Optional[str]
    title: Optional[str]
    sample_code: str
    instructions: Optional[str]
    number: int
    sct: str
    pre_exercise_code: str
    solution: str
    hint: Optional[str]
    attachments: None
    xp: int
    possible_answers: List[Any]
    feedbacks: List[Any]
    question: str
    subexercises: Optional[List["Data"]]
    course_id: Optional[int]
    chapter_id: Optional[int]
    runtime_config: Optional[str]
    language: Optional[str]

    def __init__(
        self,
        id: int,
        type: str,
        assignment: Optional[str] = None,
        title: Optional[str] = None,
        number: int = None,
        hint: Optional[str] = None,
        xp: int = None,
        possible_answers: List[Any] = None,
        feedbacks: List[Any] = None,
        course_id: Optional[int] = None,
        chapter_id: Optional[int] = None,
        runtime_config: Optional[str] = None,
        language: Optional[str] = None,
        subexercises: Optional[List["Data"]] = None,
        instructions: Optional[str] = None,
        attachments: None = None,
        sample_code: str = None,
        pre_exercise_code: str = None,
        solution: str = None,
        sct: str = None,
        question: str = None,
        **kwargs,
    ) -> None:
        self.id = id
        self.type = type
        self.assignment = assignment
        self.title = title
        self.sample_code = sample_code
        self.instructions = instructions
        self.number = number
        self.sct = sct
        self.pre_exercise_code = pre_exercise_code
        self.solution = solution
        self.hint = hint
        self.attachments = attachments
        self.xp = xp
        self.possible_answers = possible_answers
        self.feedbacks = feedbacks
        self.question = question
        self.subexercises = (
            [e.get("id") for e in subexercises] if subexercises else None
        )
        self.course_id = course_id
        self.chapter_id = chapter_id
        self.runtime_config = runtime_config
        self.language = language


class Exercise:
    data: Any
    id: int
    type: str
    version: str
    last_attempt: Optional[str]

    def __init__(
        self,
        data: Data,
        id: int,
        type: str,
        version: str,
        last_attempt: str = None,
        **kwargs,
    ) -> None:
        self.id = id
        self.type = type
        self.version = version
        if not self.is_video:
            self.data = Data(**data)
        else:
            self.data = data
        self.last_attempt = last_attempt

    @property
    def is_video(self):
        return self.type == TypeEnum.VIDEO_EXERCISE.value

    @property
    def is_python(self):
        return self.data.language == "python"

    def __str__(self) -> str:
        html = (
            "<h1> {}</h1>\n<pre><code>Exercise ID {}</code></pre>\n<h2> Assignment </h2>{}\n".format(
                self.data.title, self.id, self.data.assignment
            )
            + self.get_pre_exercise_code()
            + self.get_instructions()
            + self.get_sample_code()
            + self.get_anwsers()
            + self.get_hints()
            + self.get_solution()
        )
        return tomd.convert(html)

    def get_hints(self):
        code = "<h2> Hints </h2> {}<p></p>"
        if self.data.hint:
            return code.format(self.data.hint)
        return ""

    def get_anwsers(self):
        code = "<h2> Answers </h2>{}<p></p>"
        if self.data.possible_answers:
            return code.format(self._get_ordered_list(self.data.possible_answers))
        # return code.format("No answers were found.")
        return ""

    def get_instructions(self):
        code = "<h2> Instructions </h2>{}<p></p>"
        if self.data.instructions:
            return code.format(self.data.instructions)
        return ""

    def _get_ordered_list(self, list):
        return "<ol>{}</ol>".format("\n".join(f"<li>{i}</li>" for i in list))

    def get_solution(self):
        code = "<h2> Solution </h2>{}<p></p>"
        if self.data.feedbacks:
            return code.format(self._get_ordered_list(self.data.feedbacks))
        if self.data.solution:
            return code.format(self._get_code(self.data.solution))
        return code.format("<p>No solution was found.</p>")

    def get_sample_code(self):
        if self.data.sample_code:
            return self._get_code(self.data.sample_code)
        return ""

    def get_pre_exercise_code(self):
        code = "<h2> Pre exercise code </h2> {}<p></p>"
        if self.data.pre_exercise_code:
            return code.format(self._get_code(self.data.pre_exercise_code))
        return ""

    def _get_code(self, code):
        return f"<pre><code>{code}</code></pre>"