from django.db import models
from django.utils import timezone

from .traffic import TrafficType, traffic_type_label


class TimeInfoBase(models.Model):

    created = models.DateTimeField(default=timezone.now)
    last_modified = models.DateTimeField(default=timezone.now)

    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        if not kwargs.pop("skip_last_modified", False) and not hasattr(self, "skip_last_modified"):
            self.last_modified = timezone.now()
            if kwargs.get("update_fields") is not None:
                kwargs["update_fields"] = list({*kwargs["update_fields"], "last_modified"})

        super().save(*args, **kwargs)


class Contact(TimeInfoBase):
    email = models.EmailField(max_length=128)
    name = models.CharField(max_length=128)
    blurb = models.CharField(max_length=254, blank=True)
    subject = models.CharField(max_length=128)
    contacted = models.BooleanField(default=False)
    utm_source = models.CharField(max_length=255, blank=True, default="")
    utm_medium = models.CharField(max_length=255, blank=True, default="")
    utm_campaign = models.CharField(max_length=255, blank=True, default="")
    utm_term = models.CharField(max_length=255, blank=True, default="")
    utm_content = models.CharField(max_length=255, blank=True, default="")


class EmailMessage(TimeInfoBase):
    subject = models.CharField(max_length=255)
    body = models.TextField()
    recipient = models.EmailField()
    sent = models.BooleanField(default=False)

    def __str__(self):
        return self.recipient + " | " + self.subject


class PageVisit(models.Model):
    """First-party page view with UTM attribution and traffic classification."""

    class TrafficTypeChoices(models.TextChoices):
        HUMAN = TrafficType.HUMAN, traffic_type_label(TrafficType.HUMAN)
        AI_BOT = TrafficType.AI_BOT, traffic_type_label(TrafficType.AI_BOT)
        SEARCH_INDEXER = TrafficType.SEARCH_INDEXER, traffic_type_label(
            TrafficType.SEARCH_INDEXER
        )
        SOCIAL_BOT = TrafficType.SOCIAL_BOT, traffic_type_label(TrafficType.SOCIAL_BOT)
        MONITORING = TrafficType.MONITORING, traffic_type_label(TrafficType.MONITORING)
        OTHER_BOT = TrafficType.OTHER_BOT, traffic_type_label(TrafficType.OTHER_BOT)
        UNKNOWN = TrafficType.UNKNOWN, traffic_type_label(TrafficType.UNKNOWN)

    created = models.DateTimeField(default=timezone.now, db_index=True)
    path = models.CharField(max_length=512, db_index=True)
    query_string = models.CharField(max_length=1024, blank=True, default="")
    referrer = models.CharField(max_length=1024, blank=True, default="")
    user_agent = models.CharField(max_length=512, blank=True, default="")
    traffic_type = models.CharField(
        max_length=32,
        choices=TrafficTypeChoices.choices,
        default=TrafficTypeChoices.UNKNOWN,
        db_index=True,
    )
    utm_source = models.CharField(max_length=255, blank=True, default="", db_index=True)
    utm_medium = models.CharField(max_length=255, blank=True, default="", db_index=True)
    utm_campaign = models.CharField(
        max_length=255, blank=True, default="", db_index=True
    )
    utm_term = models.CharField(max_length=255, blank=True, default="")
    utm_content = models.CharField(max_length=255, blank=True, default="")
    session_key = models.CharField(max_length=64, blank=True, default="", db_index=True)
    is_landing = models.BooleanField(
        default=False,
        help_text="True when this request carried UTM params (campaign landing).",
    )

    class Meta:
        ordering = ["-created"]
        indexes = [
            models.Index(fields=["-created", "traffic_type"]),
            models.Index(fields=["utm_source", "utm_campaign"]),
        ]

    def __str__(self):
        return f"{self.path} ({self.traffic_type}) @ {self.created:%Y-%m-%d %H:%M}"