# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later

from datetime import date

from django.conf import settings
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.core.validators import MinValueValidator
from django.db import models, transaction
from django.db.models import Q
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from member.models import Club

#################################################################
# TO DO
# - link allergen with one food (basic or transformed) with check
# - check on basic food
# - check on transformed food
#################################################################

class QR_code(models.Model):
    """
    An QR_code model
    """
    qr_code_number = models.PositiveIntegerField(
        verbose_name=_("QR-code number"),
    )

    transformed_food_container = models.ForeignKey(
        'TransformedFood',
        on_delete = models.PROTECT,
        related_name = 'QR_code',
        null = True,
        blank = True,
        verbose_name = _('transformed food container'),
    )
    
    basic_food = models.ForeignKey(
        'BasicFood',
        on_delete = models.PROTECT,
        related_name = 'QR_code',
        null = True,
        blank = True,
        verbose_name = _('basic food'),
    )

    class Meta:
        verbose_name = _("QR-code")
        verbose_name_plural = _("QR-codes")

    def __str__(self):
        return _("QR-code number {qr_code_number}").format(qr_code_number=self.qr_code_number)

class Allergen(models.Model):
    """
    A list of allergen and alimentary restrictions
    """

    gluten = models.BooleanField(
        default = False,
        verbose_name = _('gluten'),
    )

    nut = models.BooleanField(
        default = False,
        verbose_name = _('nut'),
    )

    crustecean = models.BooleanField(
        default = False,
        verbose_name = _('crustacean'),
    )

    celery = models.BooleanField(
        default = False,
        verbose_name = _('celery'),
    )

    egg = models.BooleanField(
        default = False,
        verbose_name = _('egg'),
    )

    mustard = models.BooleanField(
        default = False,
        verbose_name = _('mustard'),
    )

    fish = models.BooleanField(
        default = False,
        verbose_name = _('fish'),
    )

    soy = models.BooleanField(
        default = False,
        verbose_name = _('soy'),
    )

    milk = models.BooleanField(
        default = False,
        verbose_name = _('milk'),
    )

    sulphite = models.BooleanField(
        default = False,
        verbose_name = _('sulphite'),
    )

    lupine = models.BooleanField(
        default = False,
        verbose_name = _('lupine'),
    )

    mollusc = models.BooleanField(
        default = False,
        verbose_name = _('mollusc'),
    )

    groundnut = models.BooleanField(
        default = False,
        verbose_name = _('groundnut'),
    )

    sesame = models.BooleanField(
        default = False,
        verbose_name = _('sesame'),
    )

    alcohol = models.BooleanField(
        default = False,
        verbose_name = _('alcohol'),
    )

    transformed_food = models.ForeignKey(
        'TransformedFood',
        on_delete = models.CASCADE,
        related_name = 'Allergen',
        blank = True,
        null = True,
        verbose_name = _('transformed food'),
    )

    basic_food = models.ForeignKey(
        'BasicFood',
        on_delete = models.CASCADE,
        related_name = 'Allergen',
        blank = True,
        null = True,
        verbose_name = _('basic food'),
    )

    class Meta:
        verbose_name = _('Allergen')
        verbose_name_plural = _('Allergens')

    def __str__(self):
        return _('Allergens of #{id}').format(id=self.id)

        


class BasicFood(models.Model):
    """
    Food which has been directly buy on supermarket
    """
    name = models.CharField(
        verbose_name=_('name'),
        max_length=255,
    )

    is_DLC = models.BooleanField(
        verbose_name=_("is DLC"),
        default=False,
    )

    is_DDM = models.BooleanField(
        verbose_name=_("is DDM"),
        default=False,
    )

    arrival_date = models.DateTimeField(
        verbose_name=_('arrival date'),
        default=timezone.now,
    )
    
    expiry_date = models.DateTimeField(
        verbose_name=_('expiry date'),
        blank=True,
        null = True,
    )
    
    owner = models.ForeignKey(
        Club,
        on_delete=models.PROTECT,
        related_name= '+',
        verbose_name=_('owner'),
    )

    label = models.ImageField(
        verbose_name=_('food label'),
        max_length=255,
        blank=False,
        null=False,
        upload_to='label/',
    )

    was_eaten = models.BooleanField(
        verbose_name=_('was eaten'),
        default = False,
    )

    transformed_food = models.ManyToManyField(
        'TransformedFood',
        related_name= 'BasicFood',
        blank = True,
        verbose_name = _('transformed food'),
    )


    class Meta:
        verbose_name=_('Basic food')
        verbose_name_plural=_('Basic foods')

    def __str__(self):
        return  self.name

    @transaction.atomic 
    def save(self, force_insert=False, force_update=False, using= None, update_fields=None):
        # Check if is_DLC and is DDM are not both True
        if self.is_DLC and self.is_DDM:
            raise ValidationError("The product cannot be a DLC and a DDM")
        return super().save(force_insert, force_update, using, update_fields)


class TransformedFood(models.Model):
    """
    Transformed food  are a mix between basic food and meal
    """
    name = models.CharField(
        max_length = 255,
        verbose_name =_('name'),
    )

    creation_date = models.DateTimeField(
        verbose_name =_('creation date'),
    )

    expiry_date = models.DateTimeField(
        verbose_name =_('expiry date'),
    )

    owner = models.ForeignKey(
        Club,
        on_delete = models.PROTECT,
        related_name = '+',
        verbose_name =_('owner'),
    )
    
    transformed_ingredient = models.ManyToManyField(
        "self",
        blank = True,
        symmetrical = False,
        related_name = 'transformed_ingredient_inv',
        verbose_name = _('transformed ingredient'),
    )
    
    is_active = models.BooleanField(
        default = True,
        verbose_name = _('is active'),
    )

    was_eaten = models.BooleanField(
        default = False,
        verbose_name = _('was eaten'),
    )


    class Meta:
        verbose_name = _('Transformed food')
        verbose_name_plural = _('Transformed foods')

    def __str__(self):
        return self.name

    @transaction.atomic
    def save(self, force_insert=False, force_update=False, using= None, update_fields=None):
        return super().save(force_insert, force_update, using, update_fields)
