from datatypes import *
from imgui_bundle import imgui, imgui_ctx, imgui_md, implot, ImVec2
import numpy as np

from model import *

class StudentInfo:
    def __init__(self):
        super().__init__()
        self.select_class = 0
        self.select_student = 0

    def student_graph(self, student_id: int) -> None:
        student = Student.get_by_id(student_id)
        clas = Class.get_by_id(student.class_id)
        lectures = Lecture.select().where(Lecture.class_id == clas.id)
        submissions = Submission.select().where(Submission.student_id == student.id)
        
        overall_points = np.sum([l.points for l in lectures])
        points = np.sum([sub.points for sub in submissions])
        if points.is_integer():
            points = int(points)

        subs_data = np.array([sub.points/l.points for sub, l in zip(submissions, lectures)])*100
        subs_labels = [str(l.title) for l in lectures]

        with imgui_ctx.begin_group():
            imgui_md.render(f"# {student.prename} {student.surname}")
            imgui_md.render(f"### {clas.name}")

            pb_content = f"{points}/{overall_points} {points/overall_points:.1%}"
            imgui.progress_bar(points/overall_points, overlay=pb_content)
                
            implot.push_colormap(implot.Colormap_.deep.value)
            if implot.begin_plot("Performance"):
                implot.setup_axes("Lectures", "Percentage")
                implot.setup_axes_limits(-1, len(subs_data), 0, 110)
                implot.setup_axis_ticks(implot.ImAxis_.x1.value, 0, len(subs_labels), len(subs_labels), subs_labels, False)
                implot.plot_bars("Submissions", subs_data)
                implot.end_plot()

    def student_list(self) -> int:
        classes = Class.select()
        content = [f"{n}. {c.name}" for n, c in enumerate(classes, start=1)]
        students = Student.select().where(Student.class_id == classes[self.select_class].id)
        lectures = Lecture.select().where(Lecture.class_id == classes[self.select_class].id)

        overall_points = np.sum([l.points for l in lectures])
        points = list()
        for student in students:
            submissions = Submission.select().where(Submission.student_id == student.id)
            cummultative = [sub.points for sub in submissions]
            passed = np.sum([p > overall_points*0.3 for p in cummultative])
            points.append((student, np.sum(cummultative)/overall_points, passed > 1))

        students = sorted(points, key=lambda x: x[1], reverse=True)

        with imgui_ctx.begin_group():
            _, self.select_class = imgui.combo("##class_list", self.select_class, content, len(content))
            for n, student in enumerate(students, start=1):
                s = student[0]
                display = f"{n}. {s.prename} {s.surname}"
                _, clicked = imgui.selectable(display, self.select_student == n-1)
                if clicked:
                    self.select_student = n-1

        return students[self.select_student][0].id

    def __call__(self):
        with imgui_ctx.begin("Student Info"):
            w, h = imgui.get_window_size()
            with imgui_ctx.begin_child("Student Selector", ImVec2(w*0.25, h*0.9)):
                id = self.student_list()
            imgui.same_line()
            with imgui_ctx.begin_child("Student Graph", ImVec2(w*0.7, h*0.9)):
                self.student_graph(id)
           
