from django.contrib.auth import get_user_model
from django.db import models
from django.shortcuts import get_object_or_404
from django_extensions.db.models import TimeStampedModel

User = get_user_model()
BNULL = {"blank": True, "null": True}


class Person(TimeStampedModel):
    """A non-system user model that can be optionally associated with a User."""

    user = models.ForeignKey(User, on_delete=models.DO_NOTHING, **BNULL)
    created_by = models.ForeignKey(
        User,
        on_delete=models.DO_NOTHING,
        **BNULL,
        related_name="created_people",
    )
    name = models.CharField(max_length=100, **BNULL)
    bgstats_id = models.UUIDField(**BNULL)
    boardgamearena_id = models.CharField(max_length=255, **BNULL)
    bgg_username = models.CharField(max_length=100, **BNULL)
    lichess_username = models.CharField(max_length=100, **BNULL)
    bio = models.TextField(**BNULL)

    def __str__(self):
        return self.name

    def get_scrobble_count(self, user=None):
        if user is None:
            user = self.created_by
        return PersonScrobble.objects.filter(person=self, user=user).count()

    def get_scrobbles(self, user=None):
        if user is None:
            user = self.created_by
        from scrobbles.models import Scrobble

        return Scrobble.objects.filter(
            id__in=PersonScrobble.objects.filter(person=self, user=user).values_list(
                "scrobble_id", flat=True
            )
        ).order_by("-timestamp")


class PersonScrobble(TimeStampedModel):
    """Tracks the relationship between a Person and a Scrobble."""

    person = models.ForeignKey(
        Person,
        on_delete=models.CASCADE,
        related_name="scrobble_associations",
    )
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name="person_scrobbles",
    )
    scrobble = models.ForeignKey(
        "scrobbles.Scrobble",
        on_delete=models.CASCADE,
    )

    class Meta:
        unique_together = ["person", "scrobble"]
        indexes = [
            models.Index(fields=["person", "user"]),
            models.Index(fields=["user", "scrobble"]),
        ]

    def __str__(self):
        return f"{self.person.name} - {self.scrobble_id}"
