from django.core.management.base import BaseCommand


class Command(BaseCommand):
    help = "Consolidate Person instances with the same name into one"

    def handle(self, *args, **options):
        consolidate_duplicate_people()


def consolidate_duplicate_people():
    """
    Find Person instances with the same name and consolidate them into one.
    Updates all scrobble logs to use the consolidated person ID.
    """
    from django.db.models import Count
    from people.models import Person, PersonScrobble
    from scrobbles.models import Scrobble

    duplicate_names = (
        Person.objects.values("name")
        .annotate(count=Count("id"))
        .filter(count__gt=1)
        .values_list("name", flat=True)
    )

    total_merged = 0
    total_scrobbles_updated = 0

    for name in duplicate_names:
        people = list(Person.objects.filter(name=name).order_by("-created"))
        if not people:
            continue

        keeper = people[0]
        duplicates = people[1:]

        print(f"\nConsolidating {len(duplicates)} duplicates of '{name}':")
        print(f"  Keeping: Person(id={keeper.id})")
        for dup in duplicates:
            print(f"  Merging: Person(id={dup.id})")

        for dup in duplicates:
            scrobbles_updated = 0

            for scrobble in Scrobble.objects.filter(log__isnull=False):
                log = scrobble.log
                changed = False

                if "with_people_ids" in log and isinstance(
                    log["with_people_ids"], list
                ):
                    if dup.id in log["with_people_ids"]:
                        log["with_people_ids"] = [
                            keeper.id if pid == dup.id else pid
                            for pid in log["with_people_ids"]
                        ]
                        changed = True

                if "players" in log and isinstance(log["players"], list):
                    for player in log["players"]:
                        if (
                            isinstance(player, dict)
                            and player.get("person_id") == dup.id
                        ):
                            player["person_id"] = keeper.id
                            changed = True

                if changed:
                    scrobble.log = log
                    scrobble.save(update_fields=["log"])
                    scrobbles_updated += 1

            PersonScrobble.objects.filter(person=dup).update(person=keeper)
            total_scrobbles_updated += scrobbles_updated
            total_merged += 1

            print(
                f"    Updated {scrobbles_updated} scrobbles, moved PersonScrobbles to keeper"
            )

            dup.delete()
            print(f"    Deleted Person(id={dup.id})")

    print(f"\n=== Summary ===")
    print(f"Total duplicate persons merged: {total_merged}")
    print(f"Total scrobbles updated: {total_scrobbles_updated}")
