"""Backfill `Token.in_use_since` for trinkets already bound to a room before
the in-use clock existed (staging cruft, user-spec 2026-06-08).

`release_lapsed_trinkets` frees a bound trinket once `in_use_since` is ≥ the
room's renewal span (7d) old. Stamping it from the earliest backing-slot
`filled_at` (when the seat was actually paid for) makes OLD bindings free on the
next sweep while RECENT ones (< 7d) keep their grace — instead of every legacy
binding releasing prematurely off a NULL clock. A binding with no filled slot
(a CARTE in the machine with no slot claimed yet) starts its clock now.
"""
from django.db import migrations


def backfill_in_use_since(apps, schema_editor):
    from django.utils import timezone

    Token = apps.get_model("lyric", "Token")
    GateSlot = apps.get_model("epic", "GateSlot")
    now = timezone.now()
    for token in Token.objects.filter(
        current_room__isnull=False, in_use_since__isnull=True
    ):
        earliest = (
            GateSlot.objects.filter(
                room_id=token.current_room_id,
                gamer_id=token.user_id,
                debited_token_type=token.token_type,
                filled_at__isnull=False,
            )
            .order_by("filled_at")
            .values_list("filled_at", flat=True)
            .first()
        )
        token.in_use_since = earliest or now
        token.save(update_fields=["in_use_since"])


class Migration(migrations.Migration):

    dependencies = [
        ("lyric", "0017_token_in_use_since"),
        ("epic", "0018_remove_sigreservation_one_sig_reservation_per_gamer_per_room_and_more"),
    ]

    operations = [
        migrations.RunPython(backfill_in_use_since, migrations.RunPython.noop),
    ]
