from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver

from scrobbles.models import Scrobble


def get_person_ids_from_log(log):
    if not log or not isinstance(log, dict):
        return set()

    person_ids = set()

    with_people_ids = log.get("with_people_ids") or []
    if isinstance(with_people_ids, list):
        person_ids.update(with_people_ids)

    players = log.get("players") or []
    if isinstance(players, list):
        for player in players:
            if isinstance(player, dict) and player.get("person_id"):
                person_ids.add(player["person_id"])

    return person_ids


@receiver(post_save, sender=Scrobble)
def sync_person_scrobbles_on_save(sender, instance, **kwargs):
    from people.models import Person, PersonScrobble

    person_ids = get_person_ids_from_log(instance.log)

    existing = set(
        PersonScrobble.objects.filter(scrobble=instance).values_list(
            "person_id", flat=True
        )
    )

    for person_id in person_ids:
        person = Person.objects.filter(id=person_id).first()
        if person and person.user and person.user == instance.user:
            continue
        if person_id not in existing:
            PersonScrobble.objects.get_or_create(
                person_id=person_id,
                user=instance.user,
                scrobble=instance,
            )

    PersonScrobble.objects.filter(scrobble=instance).exclude(
        person_id__in=person_ids
    ).delete()


@receiver(post_delete, sender=Scrobble)
def sync_person_scrobbles_on_delete(sender, instance, **kwargs):
    from people.models import PersonScrobble

    PersonScrobble.objects.filter(scrobble=instance).delete()
