# barbacompta - invoicing for dummies
# Copyright (C) 2019-2020 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from datetime import date

from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.db import models


def solde(t=None):
    '''Calcule le solde à la date à partir du dernier solde connu'''
    if t is None:
        t = date.today()
    try:
        s = SoldeBanquePop.objects.latest("date")
    except SoldeBanquePop.DoesNotExist:
        return 0
    m = s.montant
    if t == s.date:
        pass
    elif t < s.date:
        lignes = LigneBanquePop.objects.filter(date_valeur__gt=t, date_valeur__lte=s.date)
        for ligne in lignes:
            m -= ligne.montant
    elif t > s.date:
        lignes = LigneBanquePop.objects.filter(date_valeur__gt=s.date, date_valeur__lte=t)
        for ligne in lignes:
            m += ligne.montant
    return m


class Commentaire(models.Model):
    contenu = models.TextField()
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    creation = models.DateTimeField(auto_now_add=True)
    content_object = GenericForeignKey("content_type", "object_id")

    def __str__(self):
        return "Commentaire créé le %s" % self.creation


class LigneBanquePop(models.Model):
    """
    Une ligne de notre relevé de compte Banque Populaire
    """

    compte = models.CharField(max_length=20)
    date_comptabilisation = models.DateField()
    date_operation = models.DateField()
    libelle = models.TextField(max_length=256)
    reference = models.CharField(max_length=20)
    date_valeur = models.DateField(db_index=True)
    montant = models.DecimalField(max_digits=10, decimal_places=2, db_index=True)

    class Meta:
        unique_together = (
            ('compte', 'date_comptabilisation', 'date_operation', 'libelle', 'reference', 'montant'),
        )

    def __str__(self):
        return "%(date_valeur)s %(libelle)s %(montant)s" % self.__dict__

    def montant_non_affecte(self):
        return self.montant - sum(x.montant_affecte for x in self.payments.all())


class SoldeBanquePop(models.Model):
    """
    Le solde à un temps T, permet de calculer notre solde à toute date
    """

    compte = models.CharField(max_length=20)
    date = models.DateField(auto_now_add=True)
    montant = models.DecimalField(max_digits=10, decimal_places=2)
