"""
Django management command to safely normalize marketplace categories.

This command:
1. Maps existing categories to 5 allowed ones
2. Reassigns products/listings intelligently
3. Deletes unused categories
4. Is fully idempotent and supports dry-run

Usage:
    python manage.py normalize_categories --dry-run
    python manage.py normalize_categories --force
    python manage.py normalize_categories --verbose
"""

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

from market.models import MarketCategory, MarketProduct, FarmerMarketListing
from market.services.category_normalizer import CategoryNormalizer


class Command(BaseCommand):
    help = (
        "Normalize marketplace categories to exactly 5 allowed categories: "
        "Vegetables, Fruits, Grains, Dairy, Poultry. "
        "Safely maps existing categories and reassigns all products/listings. "
        "Use --dry-run to preview changes."
    )

    def add_arguments(self, parser):
        parser.add_argument(
            "--dry-run",
            action="store_true",
            help="Preview changes without applying them.",
        )
        parser.add_argument(
            "--force",
            action="store_true",
            help="Apply changes (required to avoid accidental mistakes).",
        )
        parser.add_argument(
            "--verbose",
            action="store_true",
            help="Show detailed logs of all operations.",
        )

    def handle(self, *args, **options):
        dry_run = options.get("dry_run", False)
        force = options.get("force", False)
        verbose = options.get("verbose", False)

        if not dry_run and not force:
            raise CommandError(
                "⚠️  This command requires either --dry-run or --force. "
                "Use --dry-run to preview changes first."
            )

        if dry_run and force:
            raise CommandError("Cannot use both --dry-run and --force together.")

        mode = "DRY RUN" if dry_run else "APPLY"
        self.stdout.write(self.style.WARNING(f"\n🔍 Category Normalization ({mode} mode)\n"))

        try:
            normalizer = CategoryNormalizer(
                verbosity=2 if verbose else 1,
                printer=lambda msg: self.stdout.write(msg),
            )
            result = normalizer.run(dry_run=dry_run)

            # Display results
            self._print_results(result)

            if dry_run:
                self.stdout.write(
                    self.style.SUCCESS(
                        "\n✅ Dry run complete. Use --force to apply changes.\n"
                    )
                )
            else:
                self.stdout.write(
                    self.style.SUCCESS(
                        "\n✅ Normalization complete. Database updated.\n"
                    )
                )

        except Exception as e:
            self.stdout.write(self.style.ERROR(f"\n❌ Error: {e}\n"))
            raise

    def _print_results(self, result: dict) -> None:
        """Print normalization results in a readable format."""
        self.stdout.write("\n" + "=" * 60)
        self.stdout.write("NORMALIZATION SUMMARY")
        self.stdout.write("=" * 60 + "\n")

        # Found categories
        self.stdout.write(f"📊 Categories found: {result['categories_found']}")
        if result.get("mappings"):
            self.stdout.write("   Mapped:")
            for old_name, new_name, count in result["mappings"]:
                self.stdout.write(
                    f"     • {old_name:<40} → {new_name:<20} ({count} item{'s' if count != 1 else ''})"
                )

        # Deleted categories
        if result.get("deleted_categories"):
            self.stdout.write(f"\n🗑️  Categories deleted: {len(result['deleted_categories'])}")
            for cat_name in result["deleted_categories"]:
                self.stdout.write(f"     • {cat_name}")

        # Products reassigned
        if result["products_reassigned"] > 0:
            self.stdout.write(f"\n📦 Products reassigned: {result['products_reassigned']}")

        # Listings reassigned
        if result["listings_reassigned"] > 0:
            self.stdout.write(f"\n🌾 Listings reassigned: {result['listings_reassigned']}")

        # Final state
        self.stdout.write(f"\n✅ Final categories: {result['final_categories_count']}")
        if result.get("final_categories"):
            for i, cat_name in enumerate(result["final_categories"], start=1):
                count = result.get("final_category_counts", {}).get(cat_name, 0)
                self.stdout.write(f"   {i}. {cat_name:<30} ({count:3d} items)")

        self.stdout.write("\n" + "=" * 60 + "\n")
