from imgui_bundle import (
    imgui,
    immapp,
    imgui_md,
    im_file_dialog,
    ImVec2
)

import numpy as np
from pathlib import Path
import subprocess, os, platform
from peewee import fn

from dbmodel import *
from .analyzer_state import AnalyzerState
from .plotter import plot_pie, plot_pdf

state = AnalyzerState()


@immapp.static(inited=False)
def header(group_id: int) -> None:
    statics = header 

    if group_id < 1:
        return 

    if not statics.inited:
        statics.group_id = group_id
        statics.group = Group.get_by_id(group_id)
        statics.data = [
            (s, np.sum([sub.points for sub in Submission.select().where(Submission.student_id == s.id)]))
            for s in Student.select().where(Student.group_id == group_id)
        ]
        statics.data.sort(key=lambda tup: tup[1], reverse=True)
        statics.inited = True

    if statics.group_id != group_id:
        statics.inited = False
    
    imgui_md.render(f"# {statics.group.name} - {statics.group.project}")
    imgui.text("")

    if statics.group.name != "NoGroup":
        changed, _ = imgui.checkbox("Passed", statics.group.has_passed)
        if changed:
            statics.group.has_passed = not statics.group.has_passed
            statics.group.save()

    if imgui.begin_table("Students", len(statics.data), imgui.TableFlags_.sizing_fixed_fit.value):
        for n, d in enumerate(statics.data, start=1):
            s, points = d
            if points.is_integer():
                points = int(points)
            imgui.table_next_row()
            imgui.table_next_column()
            imgui.set_next_item_width(-1)
            imgui.text(f"{n}. {s.prename} {s.surname} - {points} Points")
        imgui.end_table()
    
    

@immapp.static(inited=False)
def plot(group_id: int) -> None:
    statics = plot 
    
    if group_id < 1:
        return

    if not statics.inited:
        statics.group_id = group_id
        students = Student.select().where(Student.group_id == group_id)

        statics.data = {
            f"{s.prename} {s.surname}":
            np.sum([sub.points for sub in Submission.select().where(Submission.student_id == s.id)], dtype=np.float32)
            for s in students
         }

        data = np.array(list(statics.data.values()))
        statics.labels = list(statics.data.keys())
        statics.data = data / data.sum() * 100

        statics.inited = True

    if statics.group_id != group_id:
        statics.inited = False
    
    plot_pie(statics.data, statics.labels)


@immapp.static(inited=False)
def presentation(group_id: int) -> None:
    statics = presentation

    if group_id < 1:
        return 
    
    if not statics.inited:
        statics.group_id = group_id
        statics.group = Group.get_by_id(statics.group_id)
        statics.res = None
        statics.inited = True

    if statics.group_id != group_id:
        statics.inited = False 
    
    if statics.group.name == "NoGroup":
        return

    if not statics.group.presentation:
        imgui.text("No Presentation set for this Group")
    else:
        plot_pdf(Path(statics.group.presentation))
        imgui.same_line()

    # Button to open File Selection
    if imgui.button("Set Presentation"):
        im_file_dialog.FileDialog.instance().open(
            "SelectPresentation", "Open Presentation", "Presentation (*.pdf; *.html){.pdf,.html}"
        )

    # Handle File Dialog
    if im_file_dialog.FileDialog.instance().is_done("SelectPresentation"):
        if im_file_dialog.FileDialog.instance().has_result():
            statics.res = im_file_dialog.FileDialog.instance().get_result()
        im_file_dialog.FileDialog.instance().close()
    
    # Save path to database
    if statics.res:
        file = statics.res.path()
        statics.group.presentation = file 
        statics.group.save()
        statics.res = None
    
    imgui.same_line()
    # Open System Window for PDF 
    if statics.group.presentation and imgui.button("Open"):
        # I Hate everything about it 
        if platform.system() == 'Darwin': # MacOS
            subprocess.Popen(('open', statics.group.presentation))
        elif platform.system() == 'Windows': # Windows 
            os.startfile(statics.group.presentation)
        else: # Linux & Variants
            subprocess.Popen(('xdg-open', statics.group.presentation))


@immapp.static(inited=False)
def group_plot(class_id: int) -> None:
    if class_id < 1:
        return 

    statics = group_plot

    if not statics.inited:
        statics.class_id = class_id
        max_points = Lecture.select(fn.SUM(Lecture.points)).where(Lecture.class_id == class_id).scalar() 
        data = {
            group.name: 
                np.sum([Submission.select(fn.SUM(Submission.points)).where(Submission.student_id == s.id).scalar()
                / Student.select().where(Student.group_id == group.id).count()
                for s in Student.select().where(Student.group_id == group.id)])/max_points

            for group in Group.select().where(Group.class_id == class_id)
        }
        
        statics.labels = list(data.keys())
        data = np.array(list(data.values()))
        statics.data = data / data.sum() *100

        statics.inited = True 

    if statics.class_id != class_id:
        statics.inited = False
    
    plot_pie(statics.data, statics.labels, title="Performance per Group")

def group_graph() -> None:
    if db.is_closed():
        imgui.text("No DB loaded")
        return 
  
    w, h = imgui.get_content_region_avail()
    
    if imgui.begin_child("Header", ImVec2(w * 0.3, h*0.5), imgui.ChildFlags_.borders.value):
        header(state.group_id)
        imgui.end_child()

    imgui.same_line()

    if imgui.begin_child("Plot", ImVec2(w * 0.7, h*0.5), imgui.ChildFlags_.borders.value):
        plot(state.group_id)
        imgui.end_child()
    
    if imgui.begin_child("PDF", ImVec2(w*0.5, h*0.49), imgui.ChildFlags_.borders.value):
        #plot_pdf(Path("/storage/programming/Learnlytics/assets/MeWi_4.pdf"))
        presentation(state.group_id)
        imgui.end_child()

    imgui.same_line()

    if imgui.begin_child("Groups", ImVec2(w*0.5, h*0.49), imgui.ChildFlags_.borders.value):
        group_plot(state.class_id)
        imgui.end_child()
