"""`python manage.py provision_snapshot` — manage database snapshots.

Usage:
  python manage.py provision_snapshot create <name>
  python manage.py provision_snapshot list
  python manage.py provision_snapshot restore <name>
  python manage.py provision_snapshot delete <name>
  python manage.py provision_snapshot cleanup --keep 10
"""

from __future__ import annotations

from django.core.management.base import BaseCommand


class Command(BaseCommand):
    help = "Manage database snapshots for development and testing."

    def add_arguments(self, parser):
        sub = parser.add_subparsers(dest="action", required=True)

        create_parser = sub.add_parser("create", help="Create a new snapshot")
        create_parser.add_argument("name", help="Snapshot name (slug-friendly)")
        create_parser.add_argument("--tags", dest="tags", default="", help="Comma-separated tags")
        create_parser.add_argument("--desc", dest="description", default="", help="Description")

        sub.add_parser("list", help="List all snapshots")

        restore_parser = sub.add_parser("restore", help="Restore from a snapshot")
        restore_parser.add_argument("name", help="Snapshot name to restore")
        restore_parser.add_argument("--force", action="store_true", default=False, help="Skip confirmation")

        delete_parser = sub.add_parser("delete", help="Delete a snapshot")
        delete_parser.add_argument("name", help="Snapshot name to delete")

        cleanup_parser = sub.add_parser("cleanup", help="Remove old snapshots")
        cleanup_parser.add_argument("--keep", type=int, default=10, help="Number of latest snapshots to keep")

    def handle(self, *args: object, **options: object) -> None:
        from simorgh.apps.provisioning.snapshot import SnapshotManager

        mgr = SnapshotManager()
        action = options["action"]

        if action == "create":
            name = options["name"]
            tags = [t.strip() for t in options["tags"].split(",") if t.strip()]
            desc = options["description"]
            path = mgr.create(name, tags=tags, description=desc)
            self.stdout.write(self.style.SUCCESS(f"Snapshot created: {path}"))

        elif action == "list":
            snapshots = mgr.list_all()
            if not snapshots:
                self.stdout.write(self.style.WARNING("No snapshots found."))
                return
            self.stdout.write(f"\n  Snapshots in {mgr.storage_path}:\n")
            for snap in snapshots:
                from datetime import datetime

                ts = datetime.fromtimestamp(snap["timestamp"])
                size = snap.get("size_bytes", 0)
                size_str = f"{size / 1024:.0f} KB" if size else "unknown"
                self.stdout.write(
                    f"  {snap['name']:30s}  {ts:%Y-%m-%d %H:%M:%S}  {size_str:>10s}"
                    + (f"  tags={snap.get('tags', [])}" if snap.get("tags") else "")
                )
            self.stdout.write("")

        elif action == "restore":
            name = options["name"]
            force = options["force"]
            if not force:
                confirm = input(
                    f"This will REPLACE the current database with snapshot {name!r}. Continue? [y/N]: "
                )
                if confirm.lower() not in ("y", "yes"):
                    self.stdout.write(self.style.WARNING("Restore cancelled."))
                    return
            mgr.restore(name)
            self.stdout.write(self.style.SUCCESS(f"Snapshot {name!r} restored."))

        elif action == "delete":
            name = options["name"]
            count = mgr.delete(name)
            self.stdout.write(self.style.SUCCESS(f"Deleted {count} file(s) for snapshot {name!r}."))

        elif action == "cleanup":
            keep = options["keep"]
            removed = mgr.cleanup(keep_latest=keep)
            self.stdout.write(self.style.SUCCESS(
                f"Cleanup complete. Removed {removed} old snapshot(s), keeping latest {keep}."
            ))
