import numbers

from django import forms
from django.core.exceptions import ValidationError
from django.utils.translation import gettext
import osmnx as ox

from OSM_outils.OMSnx_enregistrement import OMSnx_enregistrement
from OSM_outils.OSMnx_recuperation_graph_information import OSMnx_recuperation_graph_information
from recuperateur_reseau_viaire.models import Graph_viaire_ville_information


class Graph_viaire_ville_informationForm(forms.Form):
    """
    Cette méthode permet de créer une nouvelle donnée dans la table Graph_viaire_ville_information

    """
    gvvi_nom = forms.CharField(required=True, label="nom de la ville ")

    def clean(self):
        """
        Cette fonction permet de créer notre propre test de validation en fonction du retour de OSMnx
        """
        cleaned_data = super(Graph_viaire_ville_informationForm, self).clean()
        nom_ville = cleaned_data['gvvi_nom']
        G = self.validation_nom_ville(nom_ville)
        recuperateur = OSMnx_recuperation_graph_information(G)
        OMSnx_enregistrement.sauvegarde_graphique(G, cleaned_data['gvvi_nom'], [])
        try:
            cleaned_data = recuperateur.recuperation_information_graphe(G, nom_ville)
        except Exception as err:
            raise ValidationError(err.__str__(), code='invalid',
                            params={'gvvi_nom': nom_ville})
        cleaned_data['gvvi_nom'] = nom_ville
        return cleaned_data

    def validation_nom_ville(self, nom_ville):
        """
                Cette fonction permet d'analyser les retours de l'argument G qui est le retour de la méthode
                OMSnx_enregistrement.recuperer_graphe_viaire_ville et de lever les erreurs.

                :param G: retour
                :raises ValidationError : si la ville est incconnue de OSMnx ou qu'elle ne possède pas de routes
        """
        if Graph_viaire_ville_information.objects.filter(gvvi_nom=nom_ville).exists():
            raise ValidationError(gettext('ville déjà enregistrée dans la base de donnée'), code='present',
                                  params={'gvvi_nom': nom_ville})
        try:
            G = OSMnx_recuperation_graph_information.lire_graphe(nom_ville)
        except FileNotFoundError:
            G = OMSnx_enregistrement.recuperer_graphe_viaire_ville(nom_ville, [])
        if isinstance(G, numbers.Real):
            if G == -1:
                raise ValidationError(gettext('ville non trouvée'), code='invalid',
                                      params={'gvvi_nom': nom_ville})
            else:
                raise ValidationError(gettext('la ville trouvée ne possède pas de routes'), code='invalid',
                                      params={'gvvi_nom': nom_ville})
        else:
            return G

    def clean_nb_intersection(self):
        data = self.cleaned_data['gvvi_nb_intersection']
        return data

    def clean_nom(self):
        data = self.cleaned_data['gvvi_nom']
        return data

class Graph_viaire_ville_informationFormUpdate(forms.Form):
    """
    Cette méthode permet de modifier une nouvelle donnée dans la table Graph_viaire_ville_information

    """
    def __init__(self, *args, **kwargs):
        initial_arguments = kwargs.get('initial', None)
        if initial_arguments:
            graph_viaire_ville_information = initial_arguments.get('valeur', None)
            super(Graph_viaire_ville_informationFormUpdate, self).__init__(*args, **kwargs)
            self.fields['gvvi_nb_intersection'] = forms.IntegerField(
                required=True, initial=graph_viaire_ville_information.gvvi_nb_intersection,
                label="nombre d'intersection "
            )
            self.fields['gvvi_nom'] = forms.CharField(required=True, initial=graph_viaire_ville_information.gvvi_nom,
                                                      label="nom de la ville ")

    def clean_nb_intersection(self):
        data = self.cleaned_data['gvvi_nb_intersection']
        return data

    def clean_nom(self):
        data = self.cleaned_data['gvvi_nb_intersection']
        return data

class Graph_viaire_ville_informationForm_delete(forms.Form):

    def __init__(self, *args, **kwargs):
        initial_arguments = kwargs.get('initial', None)
        if initial_arguments:
            graph_viaire_ville_information = initial_arguments.get('valeur', None)
            super(Graph_viaire_ville_informationForm_delete, self).__init__(*args, **kwargs)
            self.fields['gvvi_nb_intersection'] = forms.IntegerField(
                required=True, initial=graph_viaire_ville_information.gvvi_nb_intersection, disabled=True,
                label="nombre d'intersection "
            )
            self.fields['gvvi_nom'] = forms.CharField(required=True, initial=graph_viaire_ville_information.gvvi_nom,
                                                      disabled=True, label="nom de la ville ")