"""`python manage.py provision_reset` — reset/rollback provisioning fixtures.

Usage:
  python manage.py provision_reset
  python manage.py provision_reset --tenant momenin
  python manage.py provision_reset --names demo_users
  python manage.py provision_reset --dry-run
  python manage.py provision_reset --force
"""

from __future__ import annotations

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

from simorgh.apps.provisioning.services import ProvisioningService


class Command(BaseCommand):
    help = "Reset/rollback registered provisioning fixtures in reverse dependency order."

    def add_arguments(self, parser):
        parser.add_argument(
            "--tenant",
            dest="tenant_slug",
            default=None,
            help="Reset only for a specific tenant.",
        )
        parser.add_argument(
            "--workspace",
            dest="workspace_slug",
            default=None,
            help="Reset only for a specific workspace.",
        )
        parser.add_argument(
            "--dry-run",
            action="store_true",
            default=False,
            help="Preview what would be reset without executing.",
        )
        parser.add_argument(
            "--names",
            dest="names",
            default=None,
            help="Comma-separated provider names to reset (default: all).",
        )
        parser.add_argument(
            "--force",
            action="store_true",
            default=False,
            help="Skip confirmation prompt.",
        )

    def handle(self, *args: object, **options: object) -> None:
        dry_run: bool = options["dry_run"]
        tenant_slug: str | None = options["tenant_slug"]
        workspace_slug: str | None = options["workspace_slug"]
        names_str: str | None = options["names"]
        force: bool = options["force"]

        if not force and not dry_run:
            confirm = input(
                "This will DELETE data created by provisioning fixtures. Continue? [y/N]: "
            )
            if confirm.lower() not in ("y", "yes"):
                self.stdout.write(self.style.WARNING("Reset cancelled."))
                return

        service = ProvisioningService()

        names = [n.strip() for n in names_str.split(",") if n.strip()] if names_str else None

        providers = service.list_providers()
        if names:
            providers = [p for p in providers if p.name in names]
            not_found = [n for n in names if n not in {p.name for p in providers}]
            if not_found:
                raise CommandError(f"Providers not registered: {', '.join(not_found)}")

        if not providers:
            self.stdout.write(self.style.WARNING("No matching providers found."))
            return

        self.stdout.write(self.style.WARNING(
            f"Provisioning Reset — {len(providers)} provider(s)"
        ))

        context: dict = {}
        tenant = None
        workspace = None

        if tenant_slug:
            from simorgh.apps.tenants.models import Tenant

            tenant = Tenant.objects.filter(slug=tenant_slug).first()
            if tenant is None:
                raise CommandError(f"Tenant {tenant_slug!r} not found.")
            context["tenant"] = tenant
            context["tenant_id"] = tenant.pk
            context["tenant_slug"] = tenant.slug

        if workspace_slug:
            from simorgh.apps.workspaces.models import Workspace

            workspace = Workspace.objects.filter(slug=workspace_slug).first()
            if workspace is None:
                raise CommandError(f"Workspace {workspace_slug!r} not found.")
            context["workspace"] = workspace
            context["workspace_id"] = workspace.pk
            context["workspace_slug"] = workspace.slug

        if dry_run:
            self.stdout.write("\n  [DRY RUN] Reset order (reversed):")
            resolver = service.create_reset_runner(names=[p.name for p in providers])
            order = resolver._resolver.reverse_order()
            for i, p in enumerate(order, 1):
                self.stdout.write(f"    {i}. {p.name}  (scope={p.scope})")
            return

        results = service.reset(
            context=context,
            names=[p.name for p in providers],
        )

        self.stdout.write("")
        total = 0
        for r in results:
            self.stdout.write(
                self.style.WARNING(f"  {r.provider_name}: -{r.deleted} deleted")
            )
            total += r.deleted
        self.stdout.write("")
        self.stdout.write(self.style.SUCCESS(f"Reset complete. Total deleted: {total}"))
