from django.db import models
from django.db.models import Q
from django.urls import reverse
from django.utils import timezone

from apps.core.models import TimeStampedModel


class PubliciteQuerySet(models.QuerySet):
    def active(self):
        now = timezone.now()
        return self.filter(actif=True).filter(
            Q(date_debut__isnull=True) | Q(date_debut__lte=now),
            Q(date_fin__isnull=True) | Q(date_fin__gte=now),
        )

    def position(self, position):
        return self.filter(position=position)


class Publicite(TimeStampedModel):
    class Position(models.TextChoices):
        SIDEBAR = "sidebar", "Barre latérale"
        HEADER = "header", "Bannière d'en-tête"
        ARTICLE = "article", "Dans les articles"
        FOOTER = "footer", "Pied de page"

    titre = models.CharField("titre", max_length=255)
    annonceur = models.CharField("annonceur", max_length=200, blank=True)
    image = models.ForeignKey("medialib.MediaAsset", verbose_name="visuel", on_delete=models.PROTECT, related_name="+")
    lien = models.URLField("lien de destination", blank=True, max_length=500)
    position = models.CharField("emplacement", max_length=20, choices=Position.choices, default=Position.SIDEBAR, db_index=True)
    actif = models.BooleanField("active", default=True)
    date_debut = models.DateTimeField("début de diffusion", null=True, blank=True)
    date_fin = models.DateTimeField("fin de diffusion", null=True, blank=True)
    impressions = models.PositiveIntegerField("affichages", default=0)
    clics = models.PositiveIntegerField("clics", default=0)

    objects = PubliciteQuerySet.as_manager()

    class Meta:
        ordering = ["-created_at"]
        verbose_name = "publicité"

    def __str__(self):
        return self.titre

    @property
    def click_url(self):
        return reverse("public:ad-click", args=[self.pk]) if self.lien else ""

    @property
    def ctr(self):
        return round(self.clics * 100 / self.impressions, 2) if self.impressions else 0

    @property
    def diffusion_status(self):
        now = timezone.now()
        if not self.actif:
            return "inactive"
        if self.date_debut and self.date_debut > now:
            return "a_venir"
        if self.date_fin and self.date_fin < now:
            return "terminee"
        return "en_cours"
