"""
Management command to reconcile database state with YAML ideal state.

Usage:
    # Check all schemas (dry run)
    python manage.py reconcile --check

    # Reconcile all schemas
    python manage.py reconcile

    # Reconcile specific schema
    python manage.py reconcile --schema layouts

    # Check specific schema
    python manage.py reconcile --schema blueprints --check
"""

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

from lightwave.schema import DriftStatus, reconcile
from lightwave.schema.loaders.base import SCHEMA_MODEL_MAP


class Command(BaseCommand):
    help = "Reconcile database state to match YAML ideal state definitions"

    def add_arguments(self, parser):
        parser.add_argument(
            "--schema",
            type=str,
            help=f"Specific schema to reconcile. Available: {', '.join(SCHEMA_MODEL_MAP.keys())}",
        )
        parser.add_argument(
            "--check",
            action="store_true",
            help="Dry run - check for drift without applying changes",
        )
        parser.add_argument(
            "--json",
            action="store_true",
            help="Output report as JSON",
        )
        parser.add_argument(
            "--verbose",
            "-v",
            action="count",
            default=0,
            help="Increase verbosity",
        )

    def handle(self, *args, **options):
        schema_name = options.get("schema")
        check_only = options.get("check", False)
        output_json = options.get("json", False)
        verbose = options.get("verbose", 0)

        # Determine which schemas to process
        if schema_name:
            if schema_name not in SCHEMA_MODEL_MAP:
                raise CommandError(f"Unknown schema '{schema_name}'. Available: {', '.join(SCHEMA_MODEL_MAP.keys())}")
            schemas = [schema_name]
        else:
            schemas = list(SCHEMA_MODEL_MAP.keys())

        all_reports = {}
        total_missing = 0
        total_drift = 0
        total_orphan = 0
        total_error = 0

        action = "Checking" if check_only else "Reconciling"
        self.stdout.write(f"\n{action} {len(schemas)} schema(s)...\n")

        for name in schemas:
            try:
                report = reconcile(name, check_only=check_only)
                all_reports[name] = report

                # Accumulate totals
                total_missing += report.missing_count
                total_drift += report.drift_count
                total_orphan += report.orphan_count
                total_error += report.error_count

                # Output individual schema results
                if report.is_clean:
                    self.stdout.write(self.style.SUCCESS(f"✅ {name}: {report.in_sync_count} items in sync"))
                else:
                    status_parts = []
                    if report.missing_count:
                        status_parts.append(f"{report.missing_count} missing")
                    if report.drift_count:
                        status_parts.append(f"{report.drift_count} drift")
                    if report.orphan_count:
                        status_parts.append(f"{report.orphan_count} orphan")
                    if report.error_count:
                        status_parts.append(f"{report.error_count} error")

                    self.stdout.write(self.style.WARNING(f"⚠️  {name}: {', '.join(status_parts)}"))

                    # Show details if verbose
                    if verbose > 0:
                        for item in report.needs_attention:
                            if item.status == DriftStatus.MISSING:
                                self.stdout.write(f"    + MISSING: {item.key}")
                            elif item.status == DriftStatus.DRIFT:
                                fields = ", ".join(item.diff_fields)
                                self.stdout.write(f"    ~ DRIFT: {item.key} ({fields})")
                            elif item.status == DriftStatus.ORPHAN:
                                self.stdout.write(f"    ? ORPHAN: {item.key}")
                            elif item.status == DriftStatus.ERROR:
                                self.stdout.write(self.style.ERROR(f"    ✗ ERROR: {item.key} - {item.error}"))

            except Exception as e:
                self.stdout.write(self.style.ERROR(f"❌ {name}: {e}"))
                total_error += 1

        # Output JSON if requested
        if output_json:
            import json

            json_output = {name: report.to_dict() for name, report in all_reports.items()}
            self.stdout.write(json.dumps(json_output, indent=2))
            return

        # Summary
        self.stdout.write("\n" + "=" * 50)
        if total_missing == 0 and total_drift == 0 and total_error == 0:
            self.stdout.write(self.style.SUCCESS("\n✅ All schemas in sync!"))
        else:
            self.stdout.write("\nSummary:")
            if total_missing:
                action_text = "will be created" if not check_only else "need creation"
                self.stdout.write(f"  ⚠️  {total_missing} items {action_text}")
            if total_drift:
                action_text = "were updated" if not check_only else "need update"
                self.stdout.write(f"  ⚠️  {total_drift} items {action_text}")
            if total_orphan:
                self.stdout.write(f"  ❓ {total_orphan} orphan items (in DB, not in YAML)")
            if total_error:
                self.stdout.write(self.style.ERROR(f"  ❌ {total_error} errors"))

            if check_only and (total_missing or total_drift):
                self.stdout.write(self.style.NOTICE("\nRun without --check to apply changes."))
