import logging
import queue
import signal
import tkinter as tk
from tkinter import filedialog, messagebox, HORIZONTAL, VERTICAL, ttk
from gui.splash import Splash
from gui.forms import FormUi
from gui.console import ConsoleUi
from gui.status import StatusUi

from qhandler import QueueHandler


logger = logging.getLogger('spr')


def show_error(msg):
    messagebox.showerror(
        "Error del Sistema", msg)
    sys.exit()


def get_file():
    file = filedialog.askopenfilename(
        filetypes=[('Excel', '.xlsx')], title='Seleccione un archivo de subasta...')

    if not file:
        messagebox.showerror(
            "Error - Selección de Archivo", "Debe seleccionar un archivo para ejecutar la subasta!!")
        sys.exit()


def center(win):
    """
    centers a tkinter window
    :param win: the root or Toplevel window to center
    """
    win.update_idletasks()
    width = win.winfo_width()
    frm_width = win.winfo_rootx() - win.winfo_x()
    win_width = width + 2 * frm_width
    height = win.winfo_height()
    titlebar_height = win.winfo_rooty() - win.winfo_y()
    win_height = height + titlebar_height + frm_width
    x = win.winfo_screenwidth() // 2 - win_width // 2
    y = win.winfo_screenheight() // 2 - win_height // 2
    win.geometry('{}x{}+{}+{}'.format(width, height, x, y))
    win.deiconify()


class App:

    def __init__(self, root):
        self.root = root

        Splash(self.root)

        # Queue a nivel de App para manejar el progress bar
        pbqueue = queue.Queue()
        log_queue = queue.Queue()

        root.title('Simulación Predespacho del MER')
        root.iconbitmap("app.ico")

        self.queue_handler = QueueHandler(log_queue)
        formatter = logging.Formatter(
            '%(asctime)s: %(message)s', datefmt='%Y-%m-%dT%H:%M:%S')
        self.queue_handler.setFormatter(formatter)
        # self.queue_handler.setLevel(logging.INFO)
        logger.addHandler(self.queue_handler)

        w = ttk.Notebook(self.root)
        w.grid(row=1, column=0, sticky="nsew",
               padx=10, pady=(0, 10))

        tab_exec = ttk.Frame(w)

        # Create the panes and frames
        vertical_pane = ttk.PanedWindow(
            tab_exec, orient=VERTICAL)
        vertical_pane.grid(row=0, column=0, sticky="nsew", padx=10, pady=10)

        main_title = ttk.Label(
            self.root,
            text='Simulación del Predespacho del MER',
            font=('', '20', 'bold'))
        main_title.grid(row=0, column=0, pady=10)

        horizontal_pane = ttk.PanedWindow(vertical_pane, orient=HORIZONTAL)
        vertical_pane.add(horizontal_pane, weight=1)

        form_frame = ttk.Labelframe(
            horizontal_pane, text="Configuración", padding=(5, 5))
        form_frame.columnconfigure(1, weight=1)
        horizontal_pane.add(form_frame, weight=1)

        console_frame = ttk.Labelframe(
            horizontal_pane, text="Consola", padding=(5, 5))
        console_frame.columnconfigure(0, weight=1)
        console_frame.rowconfigure(0, weight=1)

        horizontal_pane.add(console_frame, weight=1)
        status_frame = ttk.Labelframe(
            vertical_pane, text="Estado", padding=(5, 5))
        vertical_pane.add(status_frame, weight=0)
        # Initialize all frames
        self.form = FormUi(form_frame, pbqueue)
        self.console = ConsoleUi(console_frame, log_queue, self.queue_handler)
        self.status = StatusUi(status_frame, pbqueue)

        w.add(tab_exec, text='Ejecución')

        # bindings

        self.root.protocol('WM_DELETE_WINDOW', self.quit)
        self.root.bind('<Control-q>', self.quit)
        signal.signal(signal.SIGINT, self.quit)

        center(self.root)

    def quit(self, *args):

        msg = 'Se esta ejecutando un proceso de optimización\n\n'
        msg += '¿Desea salir de la aplicación?'

        if self.form.runspr_thread and self.form.runspr_thread.is_alive():
            if messagebox.askokcancel("Salir de la Simulación", msg):
                logger.info('Cerrando aplicacion...')
                self.form.runspr_thread.stop()
                self.root.destroy()
        else:
            self.root.destroy()
