from django.conf import settings
from django.utils import timezone
from django.contrib.auth.models import AbstractUser
from django.db import models


class User(AbstractUser):
    """Owner / staff account.

    Custom from day one so the model can grow (phone, contact prefs, etc.)
    without the painful AUTH_USER_MODEL swap. Roles are expressed with Django's
    built-in ``is_staff`` (access to the staff admin) + groups; owners are
    ordinary authenticated users with no admin access.
    """

    # Which version of the guided tour this person has finished. Bumping
    # TOUR_VERSION re-offers the tour to everyone, which is what we want as the
    # back office keeps changing.
    tour_seen_version = models.PositiveIntegerField(default=0)


class LoginEvent(models.Model):
    """One row per sign-in attempt.

    Exists because the client explicitly asked to see "who logged in and when."
    Failed attempts are recorded too — a burst of them against one account is
    the signal that matters, and the old WordPress sites had no way to see it.
    The username is stored as text so a failed attempt for a non-existent
    account is still recorded.
    """

    #: Where the event came from. This matters more than it looks: Django
    #: stamps `last_login` for ANY call to `login()`, including a request-less
    #: one made server-side during development. That silently put "last signed
    #: in" dates against owners who had never signed in, and the owners page
    #: was read as evidence of a break-in. Only WEB and WORDPRESS events are
    #: real sign-ins by a person.
    WEB = "web"
    INTERNAL = "internal"
    WORDPRESS = "wordpress"
    SOURCES = [
        (WEB, "Browser"),
        (INTERNAL, "Server-side (not a person)"),
        (WORDPRESS, "WordPress (imported history)"),
    ]

    user = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True
    )
    username = models.CharField(max_length=254)
    succeeded = models.BooleanField(default=True)
    ip = models.GenericIPAddressField(null=True, blank=True)
    user_agent = models.CharField(max_length=300, blank=True)
    source = models.CharField(max_length=12, default=WEB, choices=SOURCES)
    # NOT auto_now_add: imported WordPress history has to carry its own date.
    occurred_at = models.DateTimeField(default=timezone.now)

    class Meta:
        ordering = ["-occurred_at"]
        indexes = [
            models.Index(fields=["-occurred_at"]),
            models.Index(fields=["user", "-occurred_at"]),
            models.Index(fields=["user", "source", "-occurred_at"]),
        ]

    def __str__(self):
        outcome = "ok" if self.succeeded else "failed"
        return f"{self.username} ({outcome}) {self.occurred_at:%Y-%m-%d %H:%M}"
