"""
Management command to list all registered FSM transition callbacks.

This command provides visibility into the callback system configuration,
showing which callbacks are registered for each model and transition.
"""

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

from apps.core.state_machine.callback_base import (
    CallbackStage,
    callback_registry,
)
from apps.core.state_machine.config import callback_config


class Command(BaseCommand):
    help = "List all registered FSM transition callbacks"

    def add_arguments(self, parser: CommandParser) -> None:
        parser.add_argument(
            "--model",
            type=str,
            help="Filter by model name (e.g., EditSubmission, Ride)",
        )
        parser.add_argument(
            "--stage",
            type=str,
            choices=["pre", "post", "error", "all"],
            default="all",
            help="Filter by callback stage",
        )
        parser.add_argument(
            "--verbose",
            "-v",
            action="store_true",
            help="Show detailed callback information",
        )
        parser.add_argument(
            "--format",
            type=str,
            choices=["text", "table", "json"],
            default="text",
            help="Output format",
        )

    def handle(self, *args, **options):
        model_filter = options.get("model")
        stage_filter = options.get("stage")
        verbose = options.get("verbose", False)
        output_format = options.get("format", "text")

        # Get all registrations
        all_registrations = callback_registry.get_all_registrations()

        if output_format == "json":
            self._output_json(all_registrations, model_filter, stage_filter)
        elif output_format == "table":
            self._output_table(all_registrations, model_filter, stage_filter, verbose)
        else:
            self._output_text(all_registrations, model_filter, stage_filter, verbose)

    def _output_text(self, registrations, model_filter, stage_filter, verbose):
        """Output in text format."""
        self.stdout.write(self.style.SUCCESS("\n=== FSM Transition Callbacks ===\n"))

        # Group by model
        models_seen = set()
        total_callbacks = 0

        for stage in CallbackStage:
            if stage_filter != "all" and stage.value != stage_filter:
                continue

            stage_regs = registrations.get(stage, [])
            if not stage_regs:
                continue

            self.stdout.write(self.style.WARNING(f"\n{stage.value.upper()} Callbacks:"))
            self.stdout.write("-" * 50)

            # Group by model
            by_model = {}
            for reg in stage_regs:
                model_name = reg.model_class.__name__
                if model_filter and model_name != model_filter:
                    continue
                if model_name not in by_model:
                    by_model[model_name] = []
                by_model[model_name].append(reg)
                models_seen.add(model_name)
                total_callbacks += 1

            for model_name, regs in sorted(by_model.items()):
                self.stdout.write(f"\n  {model_name}:")
                for reg in regs:
                    transition = f"{reg.source} → {reg.target}"
                    callback_name = reg.callback.name
                    priority = reg.callback.priority

                    self.stdout.write(f"    [{transition}] {callback_name} (priority: {priority})")

                    if verbose:
                        self.stdout.write(f"      continue_on_error: {reg.callback.continue_on_error}")
                        if hasattr(reg.callback, "patterns"):
                            self.stdout.write(f"      patterns: {reg.callback.patterns}")

        # Summary
        self.stdout.write("\n" + "=" * 50)
        self.stdout.write(self.style.SUCCESS(f"Total: {total_callbacks} callbacks across {len(models_seen)} models"))

        # Configuration status
        self.stdout.write(self.style.WARNING("\nConfiguration Status:"))
        self.stdout.write(f"  Callbacks enabled: {callback_config.enabled}")
        self.stdout.write(f"  Notifications enabled: {callback_config.notifications_enabled}")
        self.stdout.write(f"  Cache invalidation enabled: {callback_config.cache_invalidation_enabled}")
        self.stdout.write(f"  Related updates enabled: {callback_config.related_updates_enabled}")
        self.stdout.write(f"  Debug mode: {callback_config.debug_mode}")

    def _output_table(self, registrations, model_filter, stage_filter, verbose):
        """Output in table format."""
        self.stdout.write(self.style.SUCCESS("\n=== FSM Transition Callbacks ===\n"))

        # Header
        if verbose:
            header = f"{'Model':<20} {'Field':<10} {'Source':<15} {'Target':<15} {'Stage':<8} {'Callback':<30} {'Priority':<8} {'Continue':<8}"
        else:
            header = f"{'Model':<20} {'Source':<15} {'Target':<15} {'Stage':<8} {'Callback':<30}"

        self.stdout.write(self.style.WARNING(header))
        self.stdout.write("-" * len(header))

        for stage in CallbackStage:
            if stage_filter != "all" and stage.value != stage_filter:
                continue

            stage_regs = registrations.get(stage, [])
            for reg in stage_regs:
                model_name = reg.model_class.__name__
                if model_filter and model_name != model_filter:
                    continue

                if verbose:
                    row = f"{model_name:<20} {reg.field_name:<10} {reg.source:<15} {reg.target:<15} {stage.value:<8} {reg.callback.name:<30} {reg.callback.priority:<8} {str(reg.callback.continue_on_error):<8}"
                else:
                    row = f"{model_name:<20} {reg.source:<15} {reg.target:<15} {stage.value:<8} {reg.callback.name:<30}"

                self.stdout.write(row)

    def _output_json(self, registrations, model_filter, stage_filter):
        """Output in JSON format."""
        import json

        output = {
            "callbacks": [],
            "configuration": {
                "enabled": callback_config.enabled,
                "notifications_enabled": callback_config.notifications_enabled,
                "cache_invalidation_enabled": callback_config.cache_invalidation_enabled,
                "related_updates_enabled": callback_config.related_updates_enabled,
                "debug_mode": callback_config.debug_mode,
            },
        }

        for stage in CallbackStage:
            if stage_filter != "all" and stage.value != stage_filter:
                continue

            stage_regs = registrations.get(stage, [])
            for reg in stage_regs:
                model_name = reg.model_class.__name__
                if model_filter and model_name != model_filter:
                    continue

                output["callbacks"].append(
                    {
                        "model": model_name,
                        "field": reg.field_name,
                        "source": reg.source,
                        "target": reg.target,
                        "stage": stage.value,
                        "callback": reg.callback.name,
                        "priority": reg.callback.priority,
                        "continue_on_error": reg.callback.continue_on_error,
                    }
                )

        self.stdout.write(json.dumps(output, indent=2))
