import sys
import os
import os.path
from pathlib import Path
from IPython.display import Image
import ipywidgets as widgets
from ipywidgets import Layout
logo = Image(filename='../fig/wfgenes_logo.png', width = 150, height =150)
logo_output = widgets.Output(layout=Layout(width='150px', height='150px'))
with logo_output:
    display(logo)
#wfGenes_exe_path = os.path.abspath(os.path.join(os.getcwd(), '..', 'wfGenes_exe'))
#sys.path.append(wfGenes_exe_path)    
import os
import ipywidgets as widgets
import wfGenes_exe.wgenerator
import json, yaml
from ipywidgets import Button, HBox, VBox, Layout
from IPython.display import HTML, display, clear_output, Markdown as md, JSON, Javascript, FileLink, Image, display_javascript, display_html, display_json
from ipyfilechooser import FileChooser
import time
from json2html import *

# Getting the arguments with FileChooser and SelectMultiple
config = FileChooser('')
inputp = FileChooser('')

style = {'description_width': 'initial'}

model = widgets.Dropdown(
    options=['FireWorks', 'SimStack', 'Dask', 'Parsl'],
    value='FireWorks',
    description='<b>Choose a model:<b>',
    disabled=False,
    style=style
)

model_output = widgets.Output()

embedded_wms= widgets.Checkbox(
    value=False,
    description='Embedded in FireWorks',
    disabled=False,
    indent=False
)

# Set default paths for file chooser
config.default_path= '../'
inputp.default_path = '../'

# Show folder icons for file chooser
config.use_dir_icons = True
inputp.use_dir_icons = True

# Set multiple file filter patterns for config file
config.filter_pattern = ['*.txt','*.yaml','*.json', '*.yml']

# Set titles for choosers
config.title = '<b>Select a configuration file</b>'
inputp.title = '<b>Select the input path</b>'

#Button for runing wgenerator
button = widgets.Button(description='Run wfGenes', style=style, icon='play')
output = widgets.Output()

#Button for displaying Wconfig file 
dis_wconfig = widgets.Button(description='Preview WConfig', tooltip='display wconfig', icon='eye')
output2 = widgets.Output()

#Button for editing Wconfig file 
edit_wconfig = widgets.Button(description='Edit Wconfig', tooltip='Edit configuration file for modifying the graph', icon='pen')
output2 = widgets.Output()

#Button for adding another input path
plus_input = widgets.Button(tooltip='Aadding additional input paths', icon='plus', style=style, layout=Layout(width='56px'))
output3 = widgets.Output()

#Button for saving wconfig file after modifications
save_wconfig = widgets.Button(description='save', tooltip='Save wconfig after modifications', icon='save')
updated = widgets.Output()

#Text area for displaying config file
config_textarea = widgets.Textarea(
                    placeholder='Type something',
                    description='<b>Configuration file:</b>',
                    description_tooltip = 'Edit to modify the graph',
                    disabled=False,
                    style = style,
                    layout=Layout( width='100%', height='1000px')
                 )

#Dash board for displaying the graph
graph_dash = widgets.Output()

#Prepare args to wgenerator
def prepare_args(config, input):
    args = {'workflowconfig' : config.selected, 'inputpath':  inputp.selected_path , 'wms':model.value, 'embedded': embedded_wms.value}
    return args

#Run wgenerator
def run_wgenerator(args):
    png = wgenerator.run_wfgenes(args)
    return png
    
#Display graph
def display_graph(graph):
    file = open(graph, "rb") 
    image = file.read()
    graph = widgets.Image(
            value=image,
            format='png',
            height=100,
            )
    with graph_dash:
        clear_output()
        display(graph)   
    
#Define event when run wconfig button is clicked
def run_wfgenes_clicked(b):
    with output:
        clear_output()
        if config.selected == None or inputp.selected == None:
            print('Please select a configuration file and an input path.')
            time.sleep(2)
            clear_output()
            return
        args = prepare_args(config, inputp)
        png = run_wgenerator(args)
        time.sleep(1)
        display_graph(png)

#Define event when edit config button is clicked
config_output = widgets.Output()
def on_button_clicked_2(b_2):
    with config_output:
        clear_output()
        if config.selected == None:
            print('Please select a configuration file.')
            time.sleep(1.7)
            clear_output()
            return
        config_file = open(config.selected, "r")
        config_content = config_file.read()
        config_textarea.value = config_content
        display(HBox([save_wconfig, close_wconfig]))
        display(save_msg)
        display(config_textarea)
            
#Define event when WConfig preview button is clicked
config_preview = widgets.Output()
def on_wconfig_preview_clicked(b_2):
    with config_output:
        clear_output()
        if config.selected == None:
            print('Please select a configuration file.')
            time.sleep(1.7)
            clear_output()
            return
        config_file = open(config.selected, "r")
        config_content = config_file.read()
        config_split = config.selected.split('.')
        suffix_dot = len(config_split) - 1
        if config_split[suffix_dot] == 'json': 
            config_dic = json.loads(config_content)
        elif config_split[suffix_dot] == 'yaml':
            config_dic = yaml.load(config_content, Loader=yaml.Loader)
        config_to_html = json2html.convert(json = config_dic)
        config_html = HTML(config_to_html)
        display(close_wconfig)
        display_html(config_html)
            
#Define event when save wconfig button is clicked
save_msg = widgets.Output()
def on_save_wconfig_clicked(b):
    new_content = config_textarea.value
    config_file = open(config.selected, "w")
    config_file.write(new_content)
    config_file.close()
    with save_msg:
        clear_output()
        print('Configuration file was saved.')
        time.sleep(1.5)
        clear_output()

#Button to close wconfig
close_wconfig = widgets.Button(description='close', tooltip='Close wconfig', icon='close')
def on_close_wconfig_clicked(b):
    with config_output:
        clear_output()
close_wconfig.on_click(on_close_wconfig_clicked)

#Button to clear all outputs
clear_all = widgets.Button(description='Clear', tooltip='Close graph and wconfig', icon='eraser')
def on_clear_all_clicked(b):
    with graph_dash:
        clear_output()
    with config_output:
        clear_output()
    with output:
        clear_output()
    with output2:
        clear_output()
clear_all.on_click(on_clear_all_clicked)
        
#Define event when plus input button in clicked
inputpath = []
def on_button_clicked_3(b3):
    inputpath.append(FileChooser(''))
    inputpath[len(inputpath)-1].default_path = '../'
    inputpath[len(inputpath)-1].use_dir_icons = True
    with output3:
        display(inputpath[len(inputpath)-1])
        
def mdeol_changed(bvar):
    with model_output:
        clear_output()
        if model.value == 'Dask' or model.value == 'Parsl':  
            display(embedded_wms)
        
button.on_click(run_wfgenes_clicked)
edit_wconfig.on_click(on_button_clicked_2)
plus_input.on_click(on_button_clicked_3)
dis_wconfig.on_click(on_wconfig_preview_clicked)
save_wconfig.on_click(on_save_wconfig_clicked)
model.observe(mdeol_changed)

#Display buttons
def display_generator():
    """"""
    display(config)
    display(inputp)
    display(plus_input, output3)
    display(model, model_output)
    display(HBox([button, clear_all]), output)
    display(HBox([ dis_wconfig, edit_wconfig]), output2, output2, graph_dash, output3, config_output)
