# -*- coding: utf-8 -*-
#  Copyright (c) 2019-2021 Ivan LUCAS.
#  Noethysweb, application de gestion multi-activités.
#  Distribué sous licence GNU GPL.

from django.urls import reverse_lazy
from core.models import Activite, Facture, Prestation, LotFactures, FiltreListe
from core.views.base import CustomView
from django.views.generic import TemplateView
from core.utils import utils_dates, utils_dictionnaires
from facturation.utils import utils_facturation
from django.http import JsonResponse
from django.shortcuts import render
import json, datetime
from facturation.forms.factures_generation import Formulaire
from django.template import Template, RequestContext
from django.db.models import Max




def Modifier_lot_factures(request):
    action = request.POST.get("action")
    idlot = request.POST.get("id")
    nom = request.POST.get("valeur")
    donnees_extra = json.loads(request.POST.get("donnees_extra"))

    # Ajouter un lot
    if action == "ajouter":
        lot = LotFactures.objects.create(nom=nom)
        return JsonResponse({"action": action, "id": lot.pk, "valeur": lot.nom})

    # Modifier un lot
    if action == "modifier":
        lot = LotFactures.objects.get(idlot=int(idlot))
        lot.nom = nom
        lot.save()
        return JsonResponse({"action": action, "id": lot.pk, "valeur": lot.nom})

    # Supprimer un lot
    if action == "supprimer":
        try:
            lot = LotFactures.objects.get(idlot=int(idlot))
            lot.delete()
            return JsonResponse({"action": action, "id": int(idlot)})
        except:
            return JsonResponse({"erreur": "Vous ne pouvez pas supprimer cette donnée"}, status=401)

    return JsonResponse({"erreur": "Erreur !"}, status=401)


def Get_factures(data={}):
    # Période
    date_debut = utils_dates.ConvertDateENGtoDate(data["periode"].split(";")[0])
    date_fin = utils_dates.ConvertDateENGtoDate(data["periode"].split(";")[1])

    # Sélection familles
    IDfamille = None
    if data["selection_familles"] == "FAMILLE":
        IDfamille = data["famille"].pk

    # Activités
    data["activites"] = json.loads(data["activites"])
    if data["activites"]["type"] == "groupes_activites":
        liste_activites = [activite.pk for activite in Activite.objects.filter(groupes_activites__in=data["activites"]["ids"])]
    else:
        liste_activites = data["activites"]["ids"]

    # Calcul des factures
    facturation = utils_facturation.Facturation()
    dict_factures = facturation.GetDonnees(liste_activites=liste_activites, date_debut=date_debut, date_fin=date_fin, date_edition=data["date_emission"],
                                           date_echeance=data["date_echeance"], categories_prestations=data["categories"], IDfamille=IDfamille)
    liste_factures = facturation.GetListeTriee(dict_factures)
    return liste_factures



def Recherche_factures(request):
    form = Formulaire(request.POST, request=request)
    if not form.is_valid():
        html = "{% load crispy_forms_tags %} {% crispy form %} {% include 'core/messages.html' %}<script>init_page();</script>"
        data = Template(html).render(RequestContext(request, {"form": form}))
        liste_messages_erreurs = [erreur[0].message for field, erreur in form.errors.as_data().items()]
        return JsonResponse({"html": data, "erreur": "Veuillez corriger les erreurs suivantes : %s." % ", ".join(liste_messages_erreurs)}, status=401)

    # Recherche des factures à générer
    liste_factures = Get_factures(form.cleaned_data)
    return render(request, "facturation/factures_generation_selection.html", {"factures": liste_factures})



def Generation_factures(request):
    form = Formulaire(request.POST, request=request)
    if not form.is_valid():
        return JsonResponse({"html": "ERREUR!", "erreur": "Veuillez renseigner les paramètres manquants"}, status=401)

    liste_factures_cochees = json.loads(request.POST.get("liste_factures_json"))

    # Recherche des factures à générer
    liste_factures = Get_factures(form.cleaned_data)

    # Recherche le prochain numéro de facture
    numero = (Facture.objects.filter(prefixe=form.cleaned_data["prefixe"]).aggregate(Max('numero')))['numero__max']
    if not numero: numero = 0
    numero += 1

    liste_factures_generees = []
    liste_id_factures = []
    for dict_facture in liste_factures:
        if dict_facture["IDfamille"] in liste_factures_cochees:
            facture = Facture.objects.create(
                prefixe=form.cleaned_data["prefixe"],
                numero=numero,
                famille_id=dict_facture["IDfamille"],
                date_edition=form.cleaned_data["date_emission"],
                date_echeance=form.cleaned_data["date_echeance"],
                activites=";".join([str(x) for x in dict_facture["liste_activites"]]),
                individus=";".join([str(x) for x in dict_facture["individus"].keys()]),
                date_debut=form.cleaned_data["periode"].split(";")[0],
                date_fin=form.cleaned_data["periode"].split(";")[1],
                total=dict_facture["total"],
                regle=dict_facture["ventilation"],
                solde=dict_facture["solde"],
                solde_actuel=dict_facture["solde"],
                lot=form.cleaned_data["lot_factures"],
                prestations=";".join(form.cleaned_data["categories"]),
                regie=None, #todo: régie à ajouter
            )
            liste_factures_generees.append(facture)
            liste_id_factures.append(facture.pk)
            numero += 1

            # Insertion du IDfacture dans les prestations
            liste_prestations_modifiees = []
            for prestation in dict_facture["listePrestations"]:
                prestation.facture = facture
                liste_prestations_modifiees.append(prestation)
            Prestation.objects.bulk_update(liste_prestations_modifiees, ["facture"])

    # Importation des factures générées
    id_min, id_max = min(liste_id_factures), max(liste_id_factures)
    factures = Facture.objects.select_related('famille').filter(pk__gte=id_min, pk__lte=id_max).order_by("idfacture")
    nbre_factures_email = len([facture for facture in factures if facture.famille.email_factures])
    nbre_factures_impression = len(factures) - nbre_factures_email

    # Enregistre le filtre pour l'export vers le Trésor Public
    FiltreListe.objects.filter(nom="facturation.views.lots_pes_factures").delete()
    parametres = """{"champ": "idfacture", "criteres": ["%d", "%d"], "condition": "COMPRIS", "label_filtre": "Facture : Dernières factures générées"}""" % (id_min, id_max)
    FiltreListe.objects.create(nom="facturation.views.lots_pes_factures", parametres=parametres)

    # Enregistre le filtre pour l'impression
    FiltreListe.objects.filter(nom="facturation.views.factures_impression").delete()
    parametres = """{"champ": "idfacture", "criteres": ["%d", "%d"], "condition": "COMPRIS", "label_filtre": "Facture : Dernières factures générées"}""" % (id_min, id_max)
    FiltreListe.objects.create(nom="facturation.views.factures_impression", parametres=parametres)
    parametres = """{"champ": "famille__email_factures", "criteres": [], "condition": "FAUX", "label_filtre": "Famille : Activation de l'envoi des factures par Email est faux"}"""
    FiltreListe.objects.create(nom="facturation.views.factures_impression", parametres=parametres)

    # Enregistre le filtre pour l'envoi par email
    FiltreListe.objects.filter(nom="facturation.views.factures_email").delete()
    parametres = """{"champ": "idfacture", "criteres": ["%d", "%d"], "condition": "COMPRIS", "label_filtre": "Facture : Dernières factures générées"}""" % (id_min, id_max)
    FiltreListe.objects.create(nom="facturation.views.factures_email", parametres=parametres)
    parametres = """{"champ": "famille__email_factures", "criteres": [], "condition": "VRAI", "label_filtre": "Famille : Activation de l'envoi des factures par Email est vrai"}"""
    FiltreListe.objects.create(nom="facturation.views.factures_email", parametres=parametres)

    return render(request, "facturation/factures_generation_actions.html", {"factures": factures, "nbre_factures_email": nbre_factures_email, "nbre_factures_impression": nbre_factures_impression})




class View(CustomView, TemplateView):
    menu_code = "factures_generation"
    template_name = "facturation/factures_generation.html"

    def get_context_data(self, **kwargs):
        context = super(View, self).get_context_data(**kwargs)
        context['page_titre'] = "Génération des factures"
        context['box_titre'] = "Générer un lot de factures"
        context['box_introduction'] = "Veuillez renseigner les paramètres de sélection des factures à générer et cliquez sur le bouton Rechercher."
        idfamille = kwargs.get("idfamille", None)
        context['form'] = kwargs.get("form", Formulaire(request=self.request, idfamille=idfamille))
        return context

