"""Inspect and rebuild the Rekognition face collection.

  list                       show every indexed face and its owner
  purge [--external-id ID]   delete all faces, or just one user's
  reindex                    re-enroll every user that has an avatar
"""

from django.conf import settings
from django.contrib.auth import get_user_model
from django.core.management.base import BaseCommand, CommandError

from apps.hr.services.face_enrollment import sync_face_from_avatar
from apps.hr.services.rekognition import (
    delete_faces_for,
    ensure_collection,
    get_client,
    list_faces,
)

User = get_user_model()


class Command(BaseCommand):
    help = "Inspect / purge / rebuild the Rekognition face collection"

    def add_arguments(self, parser):
        parser.add_argument("action", choices=["list", "purge", "reindex"])
        parser.add_argument("--external-id", help="Limit purge to this ExternalImageId (a user uuid)")
        parser.add_argument("--collection", help="Override REKOGNITION_COLLECTION_ID")

    def handle(self, *args, **options):
        collection = options["collection"] or settings.REKOGNITION_COLLECTION_ID
        ensure_collection(collection)
        self.stdout.write(f"collection: {collection}")

        action = options["action"]
        if action == "list":
            self._list(collection)
        elif action == "purge":
            self._purge(collection, options.get("external_id"))
        else:
            self._reindex(collection)

    def _owner(self, external_id: str) -> str:
        user = User.objects.filter(pk=external_id).first()
        return user.email if user else "NO SUCH USER IN THIS DB"

    def _list(self, collection):
        faces = list_faces(collection)
        for face in faces:
            ext = face.get("ExternalImageId") or "(none)"
            self.stdout.write(f"  {face['FaceId']}  {ext}  {self._owner(ext)}")
        self.stdout.write(f"total: {len(faces)}")

    def _purge(self, collection, external_id):
        if external_id:
            deleted = delete_faces_for(external_id, collection)
            self.stdout.write(self.style.SUCCESS(f"deleted {deleted} face(s) for {external_id}"))
            return

        faces = list_faces(collection)
        if not faces:
            self.stdout.write("collection already empty")
            return
        face_ids = [f["FaceId"] for f in faces]
        for i in range(0, len(face_ids), 1000):  # DeleteFaces caps at 1000 per call
            get_client().delete_faces(CollectionId=collection, FaceIds=face_ids[i:i + 1000])
        self.stdout.write(self.style.SUCCESS(f"deleted {len(face_ids)} face(s)"))

    def _reindex(self, collection):
        if collection != settings.REKOGNITION_COLLECTION_ID:
            raise CommandError(
                "reindex writes to the configured collection; set REKOGNITION_COLLECTION_ID "
                "instead of passing --collection"
            )
        users = User.objects.exclude(avatar="").exclude(avatar__isnull=True)
        indexed = skipped = 0
        for user in users:
            if sync_face_from_avatar(user):
                indexed += 1
                self.stdout.write(f"  indexed  {user.email}")
            else:
                skipped += 1
                self.stdout.write(self.style.WARNING(f"  no face  {user.email}"))
        self.stdout.write(self.style.SUCCESS(f"indexed {indexed}, skipped {skipped}"))
