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

from pathlib import Path
from itertools import compress 
import io
import pickle
from dataclasses import dataclass

from PIL import Image
import numpy as np 
import cairosvg
from slugify import slugify

from dbmodel import *
from pdf import *
from .plotter import plot_pdf
from .analyzer_state import AnalyzerState 
state = AnalyzerState()


@dataclass
class DocumentProperties:
    logo: Path
    save_dir: Path 
    file_name: str
    author: str


def svg_to_png(svg: Path) -> Image:
    with open(svg) as f:
        svg = f.read()
    return Image.open(io.BytesIO(cairosvg.svg2png(svg))).convert("RGBA")


def dump_properties(properties: DocumentProperties) -> None:
    with open('./pickles/document_properties.pkl', 'wb') as f:
        pickle.dump(properties, f)


def load_properties() -> DocumentProperties:
    try:
        with open('./pickles/document_properties.pkl', 'rb') as f:
            properties = pickle.load(f)
        return properties
    except FileNotFoundError:
        return None

file = Path('./pickles/document_properties.pkl') 
try:
    file.resolve(strict=True)
    
except FileNotFoundError:
    dump_properties(DocumentProperties(
        logo = Path("./assets/learnlytics.svg"),
        save_dir = Path.home(),
        file_name = "document",
        author = "Learnlytics"
    ))


@immapp.static(inited=False)
def document_properties(class_id: int) -> None:
    # TO DO: Store Properties persistent
    statics = document_properties

    if not statics.inited:
        statics.properties = load_properties()
        if not statics.properties:
            statics.properties = DocumentProperties(
                logo = Path("./assets/learnlytics.svg"),
                save_dir = Path.home(),
                file_name = "document",
                author = "Learnlytics"
            )
        statics.image = svg_to_png(statics.properties.logo) if statics.properties.logo.suffix == ".svg" else Image.open(statics.properties.logo)        
        statics.inited = True

    imgui_md.render_unindented('### Properties')
    imgui.text("")
    
    if imgui.begin_table("Properties", 2, imgui.TableFlags_.sizing_fixed_fit.value):
        imgui.table_next_row()
        imgui.table_next_column()
        imgui.text("Author:")
        imgui.table_next_column()
        changed, statics.properties.author = imgui.input_text("", statics.properties.author)
        if changed:
            dump_properties(statics.properties)

        imgui.table_next_row()
        imgui.table_next_column()
        if imgui.button("Add Logo"):
            im_file_dialog.FileDialog.instance().open(
                "SelectLogo", "Open Logo", "Logo (*.png; *.jpg; *.jpeg; *.svg){.png,.jpg,.jpeg,.svg}", False, str(Path.home())
            )
        imgui.table_next_column()
        imgui.text(str(statics.properties.logo))

        imgui.table_next_row()
        imgui.table_next_column()
        if imgui.button("Save to"):
            im_file_dialog.FileDialog.instance().open(
                "SelectSaveDir", "Select Save Directory", "", False, str(Path.home())
            ) 
        imgui.table_next_column()
        imgui.text(str(statics.properties.save_dir))

        imgui.table_next_row()
        imgui.table_next_column()
        if imgui.button("Generate Name"):
            date = datetime.now()
            statics.properties.file_name = slugify(f'{Class.get_by_id(class_id).name}_{date.strftime("%a_%d.%m.%Y_%H:%M")}')
        imgui.table_next_column()
        changed, statics.properties.file_name = imgui.input_text(".pdf", statics.properties.file_name)
        if changed:
            dump_properties(statics.properties)
        imgui.end_table()

    if statics.properties.logo:
        w, h = imgui.get_content_region_avail()
        x, y = statics.image.size
        size = (
            int(x) if x < w*0.8 else int(w*0.8),
            int(y) if y < h*0.5 else int(h*0.5)
        )
        immvision.image_display("Logo", np.array(statics.image), size, True)

    if im_file_dialog.FileDialog.instance().is_done("SelectLogo"):
        if im_file_dialog.FileDialog.instance().has_result():
            statics.properties.logo = im_file_dialog.FileDialog.instance().get_result()
            statics.properties.logo = Path(statics.properties.logo.path()).relative_to(Path('.').resolve())
            statics.image = svg_to_png(statics.properties.logo) if statics.properties.logo.suffix == ".svg" else Image.open(statics.properties.logo)
            dump_properties(statics.properties)
        im_file_dialog.FileDialog.instance().close()

    if im_file_dialog.FileDialog.instance().is_done("SelectSaveDir"):
        if im_file_dialog.FileDialog.instance().has_result():
            save_dir = im_file_dialog.FileDialog.instance().get_result()
            statics.properties.save_dir = Path(save_dir.path())
            dump_properties(statics.properties)
        im_file_dialog.FileDialog.instance().close()   
    
    return statics.properties

@immapp.static(inited=False)
def filters(class_id: int) -> list[Study]:
    statics = filters

    if not statics.inited:
        statics.class_id = class_id
        statics.studys = list(Study.select())
        statics.checked = [True] * len(statics.studys)
        statics.inited = True
    
    if statics.class_id != class_id:
        statics.inited = False
    
    if Study.select().count() != len(statics.studys):
        statics.inited = False

    imgui_md.render_unindented("### Study Filters")
    imgui.text("")

    if imgui.begin_table("Create", 2, imgui.TableFlags_.sizing_fixed_fit.value):
        for n, study in enumerate(statics.studys):
            imgui.table_next_row()
            imgui.table_next_column()
            _, statics.checked[n] = imgui.checkbox(f"##{study.name}", statics.checked[n])
            imgui.table_next_column() 
            imgui.text(study.name)
        imgui.end_table()

    return list(compress(statics.studys, statics.checked))


@immapp.static(inited=False)
def order_by() -> str:
    statics = order_by

    if not statics.inited:
        statics.order_by = ["Study Program", "Group", "Ranking"]
        statics.selected = 1
        statics.inited = True
    
    imgui_md.render_unindented("### Order by")
    imgui.text("")
    if imgui.begin_table("Order", 2, imgui.TableFlags_.sizing_fixed_fit.value):
        for n, order in enumerate(statics.order_by):
            imgui.table_next_row()
            imgui.table_next_column()
            if imgui.radio_button(f"## {order}", statics.selected == n):
                statics.selected = n
            imgui.table_next_column()
            imgui.text(order)
        imgui.end_table()

    return statics.order_by[statics.selected]

@immapp.static(inited=False)
def create_document(class_id: int) -> None:
    imgui_md.render_unindented("# Create Documents")
    
    statics = create_document
    if not statics.inited:
        statics.class_id = class_id
        
        try:
            with open("./pickles/last_file.txt") as f:
                statics.file = Path(f.read())
        except FileNotFoundError:
            statics.file = None

        statics.order_by = None

        statics.inited = True
    
    if statics.class_id != class_id:
        statics.inited = False
    
    w, h = imgui.get_content_region_avail()
    if imgui.begin_child("PDF", ImVec2(w*0.45, h), imgui.ChildFlags_.borders.value):
        imgui_md.render_unindented('### Document')
        imgui.text("")
        if statics.file:
            plot_pdf(statics.file, "Viewer")
        else:
            imgui.text("No document created yet.")
    imgui.end_child()
    
    imgui.same_line()

    if imgui.begin_child("Filters", ImVec2(w*0.54, h), imgui.ChildFlags_.borders.value):
        w1, h1 = imgui.get_content_region_avail()
        if imgui.begin_child("Study Filters", ImVec2(w1, h1*0.2)):
            study_filters = filters(statics.class_id)  
            imgui.end_child()

        if imgui.begin_child("Order By", ImVec2(w1, h1*0.2)):
            statics.order_by = order_by()
            imgui.end_child()
        
        if imgui.begin_child("Document Properties", ImVec2(w1, h1*0.58)):
            properties = document_properties(statics.class_id)
            if imgui.button("Create"):
                pdf, css = get_pdf(statics.class_id)
                header = get_pdf_header_creator(state.class_id, [study.name for study in study_filters], properties.author, properties.logo)

                match statics.order_by:
                    case "Group":
                        sections = create_group_pdf(statics.class_id, study_filters) 
                
                    case "Study Program":    
                        sections = create_study_pdf(statics.class_id, study_filters) 
                     
                    case 'Ranking':
                        sections = create_ranking_pdf(statics.class_id, study_filters)

                pdf.add_section(header, user_css=css)
                for section in sections:
                    pdf.add_section(section, user_css=css)
                statics.file = properties.save_dir / (properties.file_name + ".pdf")
                pdf.save(statics.file)
                with open("./pickles/last_file.txt", "w") as f:
                    f.write(str(statics.file))

            imgui.end_child()
        imgui.end_child()
    imgui.same_line()
    

def document_creator():
    create_document(state.class_id)
