import os
import shutil
import sys
import pathlib
import pickle

from hashlib import sha256

from uuid import uuid4

from munyal.misc import alert
from munyal.misc import get_os
from munyal.misc import path_join


def __get_config_folder():
    _os = get_os()
    if _os == "linux":
        folder = path_join(os.getenv("HOME"), ".munyal")
    else:
        folder = path_join(os.path.expandvars("%APPDATA%"), "Munyal")
    return folder

def __get_files_folder():
    folder = path_join(os.path.expanduser("~"), "Munyal")
    return folder

def get_last_history():
    last_history_path = path_join(__get_config_folder(), "history.pkl")
    if not os.path.exists(last_history_path):
        return None
    with open(last_history_path, "rb") as history:
        return pickle.load(history)

def set_last_history(last_history):
    last_history_path = path_join(__get_config_folder(), "history.pkl")
    with open(last_history_path, "wb") as history:
        pickle.dump(last_history, history)

def get_config():
    for _ in range(3):
        try:
            config = __get_config()
        except EOFError:
            config = None
        if not config:
            try:
                gui_config()
            except ModuleNotFoundError as e:
                cli_config()
        else:
            return config


def __get_config():
    folder = __get_config_folder()
    config_file = path_join(folder, "config")
    if os.path.exists(config_file):
        config_bytes = open(config_file, "rb")
        config = pickle.load(config_bytes)
        config_bytes.close()
        return config


def __validate_values(user, password):
    return True


def _gui_validate_config(root, user, password, folder):
    passwd_hash = sha256(password.get().encode("utf-8")).hexdigest()
    if not user:
        alert(root, "Introduce tu usuario de la red Munyal")
    elif not password:
        alert(root, "Introduce tu contraseña")
    elif not folder:
        alert(root, "Elige la carpeta que quieres sincronizar")
    elif not __validate_values(user, passwd_hash):
        alert(
            root,
            "Tu usuario o contraseña son incorrectos, favor de reintentarlo")
    else:
        password.set("")
        __set_config(user, passwd_hash, folder)
        root.destroy()


def _cli_validate_config(user, password, folder):
    if not user:
        print("! Introduce tu usuario de la red munyal !")
    elif not password:
        print("! Introduce tu contraseña !")
    elif not folder:
        print("! Elige la carpeta que quieres sincronizar !")
    elif not __validate_values(user, passwd_hash):
        print("! Tu usuario o contraseña son incorrectos !")
    else:
        return True
    return False


def __set_config(user, password, folder):
    folder_config = __get_config_folder()
    # Create config folder
    path = pathlib.Path(folder_config)
    path.mkdir(parents=True, exist_ok=True)
    # Create Munyal folder
    path = pathlib.Path(folder)
    path.mkdir(parents=True, exist_ok=True)

    with open(path_join(folder_config, "config"), "wb") as config_file:
        config_file.write(
            pickle.dumps({
                "login": {
                    "user": user,
                    "password": password
                },
                "folder": folder,
                "uuid": str(uuid4())
            }))


def gui_config():
    from tkinter import Button, Entry, Label, StringVar, Tk, filedialog
    from PIL import Image, ImageTk

    root = Tk()
    root.geometry("250x420")

    img_logo = Image.open("img/logo.png")
    img_tk = ImageTk.PhotoImage(img_logo.resize((200, 150), Image.ANTIALIAS))

    host = StringVar()
    host.set("localhost")
    host_field = Entry(root, textvariable=host)

    passwd = StringVar()
    passwd_field = Entry(root, textvariable=passwd, show="*")

    folder = StringVar()
    folder.set(__get_files_folder())
    folder_field = Entry(root, textvariable=folder)
    btn_folder = Button(root,
                        text="Examinar",
                        command=lambda: search_folder(folder))

    connect = Button(
        root,
        text="Conectar",
        command=lambda: _gui_validate_config(root, host.get(), passwd, folder.get()))

    Label(root, text="MUNYAL").pack()
    Label(root, image=img_tk).pack()
    Label(root, text="").pack()
    Label(root, text="Ruta del servidor").pack()
    host_field.pack()
    Label(root, text="").pack()
    Label(root, text="Contraseña").pack()
    passwd_field.pack()
    Label(root, text="").pack()
    Label(root, text="Carpeta a sincronizar").pack()
    folder_field.pack()
    btn_folder.pack()
    Label(root, text="").pack()
    connect.pack()

    root.mainloop()


def cli_config():
    while True:
        host = input("Introduce tu usuario de Munyal\n>>> ")
        password = input("Introduce tu contraseña\n>>> ")
        folder = input("Introduce el directorio que quieres sincronizar\n>> ")
        if _cli_validate_config(host, password, folder):
            break
        else:
            print("! Los datos introducidos no son correctos, intentalo de nuevo !")
    passwd_hash = sha256(password.encode("utf-8")).hexdigest()
    __set_config(user, password, folder)


def search_folder(field):
    path = filedialog.askdirectory()
    field.set(path)


if __name__ == "__main__":
    if "--restart" in sys.argv:
        if get_config():
            shutil.rmtree(__get_config_folder())
    print(get_config())