import uuid

from django.core.management.base import BaseCommand, CommandError
from django.db import transaction

from api.models import TtActivity, TtLocation, TtStaff
from api.services.integration.outbox import (
    append_activity_event,
    append_resource_event,
    finalize_change_set,
)


class Command(BaseCommand):
    help = "Seed canonical lifecycle/allocation snapshots through the ordinary versioned outbox protocol."

    def add_arguments(self, parser):
        parser.add_argument("--aggregate", choices=["staff", "location", "activity"], required=True)
        parser.add_argument("--after-id", type=int, default=0)
        parser.add_argument("--batch-size", type=int, default=500)
        parser.add_argument("--actor-id", type=int)

    def handle(self, *args, **options):
        batch_size = options["batch_size"]
        if batch_size < 1 or batch_size > 5000:
            raise CommandError("--batch-size must be between 1 and 5000")
        aggregate = options["aggregate"]
        model = {"staff": TtStaff, "location": TtLocation, "activity": TtActivity}[aggregate]
        queryset = model.objects.filter(id__gt=options["after_id"]).order_by("id")[:batch_size]
        if aggregate == "activity":
            queryset = queryset.select_related("academic_term", "week_pattern").prefetch_related(
                "week", "week_pattern__week", "staff", "location", "student_set"
            )
        items = list(queryset)
        with transaction.atomic():
            change_set_id = uuid.uuid4()
            for item in items:
                if aggregate == "activity":
                    append_activity_event(
                        activity=item,
                        activity_id=item.id,
                        action="snapshot",
                        previous=None,
                        actor_id=options["actor_id"],
                        origin="reconciliation_seed",
                        change_set_id=change_set_id,
                        defer_change_set_finalization=True,
                    )
                else:
                    append_resource_event(
                        item,
                        action="snapshot",
                        previous=None,
                        actor_id=options["actor_id"],
                        origin="reconciliation_seed",
                        change_set_id=change_set_id,
                        defer_change_set_finalization=True,
                    )
            if items:
                finalize_change_set(change_set_id)
        if items:
            self.stdout.write(f"seeded={len(items)} next_after_id={items[-1].id}")
        else:
            self.stdout.write("seeded=0")
