from django.shortcuts import get_object_or_404, render
import os
from django.conf import settings
# Create your views here.
from django.http import HttpResponse

from recuperateur_reseau_viaire.forms import Graph_viaire_ville_informationForm, \
    Graph_viaire_ville_informationFormUpdate, Graph_viaire_ville_informationForm_delete, \
    Graph_viaire_ville_informationForm_export
from recuperateur_reseau_viaire.models import Graph_viaire_ville_information

from recuperateur_reseau_viaire.admin import Graph_viaire_ville_informationResource
from OSM_outils.OSMnx_recuperation_graph_information import OSMnx_recuperation_graph_information


def index(request):
    if request.GET.__contains__("bouton") and request.GET.getlist("bouton")[0] == "update" \
            and request.GET.__contains__("update"):
        return update(request, request.GET.getlist("update"))
        form = Graph_viaire_ville_informationForm()
    elif request.method == 'POST':
        form = Graph_viaire_ville_informationForm(request.POST)
        graph_viaire_ville_information_instance = Graph_viaire_ville_information()
        if form.is_valid():
            for clef in form.cleaned_data.keys():
                graph_viaire_ville_information_instance.__setattr__(clef, form.cleaned_data[clef])
            graph_viaire_ville_information_instance.save()
            return render(request, 'recuperateur_reseau_viaire/valide.html',
                          {'instance' : graph_viaire_ville_information_instance})
    else:
        form = Graph_viaire_ville_informationForm()
    graph_viaire_ville_information_list = Graph_viaire_ville_information.objects.all()
    return render(request, 'recuperateur_reseau_viaire/index.html',
            {'list_graph' : graph_viaire_ville_information_list, 'form' : form})

def valide(request):
    return render(request, 'recuperateur_reseau_viaire/valide.html')

def update(request, graph_id):
    """
    Cette méthode permet de mettre à jour une ligne de la table Graph_viaire_ville_information. Elle prend en paramètre
    la requête et la clef primaire.

    Cette méthode permet de gérer l'affichage ainsi que les modifications dans la base de donnée en
    fonction du formulaire compris dans la requête.

    Le formulaire se présente sous la forme suivante : un dictionnaire cleaned_data associant à un champ de formulaire,
    la valeur donné par l'utilisateur. Nous avons ici deux champs de formulaire pour chaque variable de la table
    Graph_viaire_ville_information :
     - le champ et la valeur préremplit par la table ou modifié par l'utilisateur
     - une case à cocher, si la case à cocher lla variable est modifié par la fonction associée dans la classe
     OSMnx_recuperation_graph_information

    en cas de succès la page valide.html est affichée

    :param request:
    :param graph_id:
    :return:
    """
    if isinstance(graph_id, int):
        graph_viaire_ville_information_instance = Graph_viaire_ville_information.objects.filter(id=graph_id)[0]
    elif isinstance(graph_id, list):
        graph_viaire_ville_information_instance = []
        for id in graph_id:
            graph_viaire_ville_information_instance.append(Graph_viaire_ville_information.objects.filter(id=id)[0])
    else:
        return 1
    if request.method == 'POST':
        form_u = Graph_viaire_ville_informationFormUpdate(request.POST,
                                                          initial={'valeur' : graph_viaire_ville_information_instance})
        if form_u.is_valid():
            var_OSMnx_recuperation_graph_information = OSMnx_recuperation_graph_information(None)
            liste_fonction_recup_graph_information = var_OSMnx_recuperation_graph_information.sgbd_liste_fonction()
            tableau_associatif_nom_variable_nom_fonction = {}
            for func in liste_fonction_recup_graph_information:
                retour = getattr(var_OSMnx_recuperation_graph_information, func)(None)
                nom_variable_sgbd = next(iter(retour))
                tableau_associatif_nom_variable_nom_fonction[nom_variable_sgbd] = {"nom_fonction" : func}
            if not isinstance(graph_viaire_ville_information_instance, list):
                graph_viaire_ville_information_instance = [graph_viaire_ville_information_instance]
            for gvvi_instance in graph_viaire_ville_information_instance:
                G = OSMnx_recuperation_graph_information.lire_graphe(gvvi_instance.gvvi_nom)
                var_OSMnx_recuperation_graph_information = OSMnx_recuperation_graph_information(G)
                for sgbd_var in dir(graph_viaire_ville_information_instance[0]):
                    if sgbd_var.startswith("gvvi_") and not sgbd_var.endswith("_check"):
                        if form_u.cleaned_data.get(sgbd_var + '_check'):
                            gvvi_instance.\
                                __setattr__(sgbd_var,
                                            getattr(var_OSMnx_recuperation_graph_information,
                                                    tableau_associatif_nom_variable_nom_fonction[sgbd_var]["nom_fonction"])(G)[sgbd_var])
                        elif form_u.cleaned_data.get(sgbd_var) is not None:
                            gvvi_instance.__setattr__(sgbd_var, form_u.cleaned_data[sgbd_var])
                gvvi_instance.save()
            return render(request, 'recuperateur_reseau_viaire/valide.html',
                          {'instance': graph_viaire_ville_information_instance})
    else:
        form_u = Graph_viaire_ville_informationFormUpdate(initial={'valeur' : graph_viaire_ville_information_instance})
        return render(request, "recuperateur_reseau_viaire/update.html", {'form_u' : form_u})

def delete(request, graph_id):
    graph_viaire_ville_information_instance = Graph_viaire_ville_information.objects.filter(id=graph_id)[0]
    if request.method == 'POST':
        form_u = Graph_viaire_ville_informationForm_delete(request.POST,
                                                          initial={'valeur': graph_viaire_ville_information_instance})
        if form_u.is_valid():
            graph_viaire_ville_information_instance.gvvi_nom = form_u.cleaned_data['gvvi_nom']
            graph_viaire_ville_information_instance.gvvi_nb_intersection = form_u.cleaned_data['gvvi_nb_intersection']
            if os.path.isfile(os.path.join(settings.REGISTER_DIR, form_u.cleaned_data['gvvi_nom'] + ".graphml")):
                os.remove(os.path.join(settings.REGISTER_DIR, form_u.cleaned_data['gvvi_nom'] + ".graphml"))
            graph_viaire_ville_information_instance.delete()
            return render(request, 'recuperateur_reseau_viaire/valide.html',
                          {'instance': graph_viaire_ville_information_instance})
    else:
        form_u = Graph_viaire_ville_informationForm_delete(initial={'valeur': graph_viaire_ville_information_instance})
        return render(request, "recuperateur_reseau_viaire/delete.html", {'form_d': form_u})


def export(request):
    if request.method == 'POST':
        form_e = Graph_viaire_ville_informationForm_export(request.POST,
                                                          initial={'formats_exports': format})
        if form_e.is_valid():
            sgbd_donnees = getattr(Graph_viaire_ville_informationResource().export(),
                              Graph_viaire_ville_information.formats_exports[int(form_e.cleaned_data['choix_format_export'])][1])()
            fichier = open(settings.REGISTER_DIR + "/export_sgbd." + Graph_viaire_ville_information.formats_exports[int(form_e.cleaned_data['choix_format_export'])][1].removeprefix("get_"), "w")
            fichier.write(sgbd_donnees)
            fichier.close()
            graph_viaire_ville_information_instance = Graph_viaire_ville_information()
            return render(request, 'recuperateur_reseau_viaire/valide.html',
                          {'instance': graph_viaire_ville_information_instance})

    else:

        form_e = Graph_viaire_ville_informationForm_export(request.POST,
                                                           initial={'formats_exports': format})
        return render(request, 'recuperateur_reseau_viaire/export.html', {'form_e': form_e})


def atributs_graph(request, graph_id):
    graph = get_object_or_404(Graph_viaire_ville_information, graph_id)
    return render(request, 'recuperateur_reseau_viaire/graph_id.html', {'graph' : graph})
