"""
Django Management Command for MCP Inspector

Provides interactive testing and inspection of MCP tools exposed from DRF views.

Usage:
    python manage.py mcp_inspector [--namespace PREFIX] [--output FORMAT]
"""

import json
import logging
from typing import Optional

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

from drf_mcp.discovery import EndpointScanner
from drf_mcp.schema import SchemaConverter

logger = logging.getLogger(__name__)


class Command(BaseCommand):
    """
    MCP Inspector Django Management Command
    
    Inspects and tests MCP tools exposed from DRF views.
    """

    help = "Inspect and test MCP tools generated from Django REST Framework views"

    def add_arguments(self, parser):
        """Add command arguments"""
        parser.add_argument(
            "--namespace",
            type=str,
            default="drf",
            help="Namespace prefix for tools (default: drf)",
        )
        parser.add_argument(
            "--output",
            type=str,
            choices=["json", "table", "text"],
            default="table",
            help="Output format for tools list",
        )
        parser.add_argument(
            "--endpoint",
            type=str,
            help="Filter tools for a specific endpoint path",
        )
        parser.add_argument(
            "--list-only",
            action="store_true",
            help="Only list discovered tools, don't enter interactive mode",
        )

    def handle(self, *args, **options):
        """Execute command"""
        try:
            self.namespace = options["namespace"]
            self.output_format = options["output"]
            self.endpoint_filter = options.get("endpoint")
            self.list_only = options.get("list_only", False)

            # Discover endpoints
            scanner = EndpointScanner()
            endpoints = scanner.scan()

            if not endpoints:
                self.stdout.write(
                    self.style.WARNING("No DRF endpoints found in URLconf.")
                )
                return

            # Filter by endpoint if specified
            if self.endpoint_filter:
                endpoints = [
                    e for e in endpoints if self.endpoint_filter in e.path
                ]
                if not endpoints:
                    raise CommandError(
                        f"No endpoints matching filter: {self.endpoint_filter}"
                    )

            # Display tools
            self._display_tools(endpoints)

            if not self.list_only:
                self._interactive_mode(endpoints)

        except Exception as e:
            logger.error(f"MCP Inspector error: {e}", exc_info=True)
            raise CommandError(f"Inspector failed: {e}") from e

    def _display_tools(self, endpoints):
        """Display discovered tools"""
        self.stdout.write(
            self.style.SUCCESS(f"\n✓ Discovered {len(endpoints)} endpoints\n")
        )

        if self.output_format == "json":
            self._display_json(endpoints)
        elif self.output_format == "table":
            self._display_table(endpoints)
        else:
            self._display_text(endpoints)

    def _display_json(self, endpoints):
        """Display tools as JSON"""
        tools = []
        schema_converter = SchemaConverter()

        for endpoint in endpoints:
            tool_data = {
                "path": endpoint.path,
                "view": endpoint.view_class.__name__,
                "is_viewset": endpoint.is_viewset,
                "methods": endpoint.http_methods,
                "actions": endpoint.actions or {},
            }

            # Add schema if available
            if hasattr(endpoint.view_class, "serializer_class"):
                try:
                    serializer = endpoint.view_class.serializer_class()
                    schema = schema_converter.serialize_to_schema(serializer)
                    tool_data["schema"] = schema
                except Exception as e:
                    tool_data["schema_error"] = str(e)

            tools.append(tool_data)

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

    def _display_table(self, endpoints):
        """Display tools as ASCII table"""
        from tabulate import tabulate

        rows = []
        for endpoint in endpoints:
            rows.append([
                endpoint.path,
                endpoint.view_class.__name__,
                "ViewSet" if endpoint.is_viewset else "APIView",
                ", ".join(endpoint.http_methods),
            ])

        headers = ["Path", "View Class", "Type", "Methods"]
        self.stdout.write(tabulate(rows, headers=headers, tablefmt="grid"))
        self.stdout.write("")

    def _display_text(self, endpoints):
        """Display tools as formatted text"""
        for i, endpoint in enumerate(endpoints, 1):
            self.stdout.write(
                self.style.HTTP_INFO(f"{i}. {endpoint.view_class.__name__}")
            )
            self.stdout.write(f"   Path: {endpoint.path}")
            self.stdout.write(f"   Type: {'ViewSet' if endpoint.is_viewset else 'APIView'}")
            self.stdout.write(f"   Methods: {', '.join(endpoint.http_methods)}")
            if endpoint.actions:
                self.stdout.write(f"   Actions: {endpoint.actions}")
            self.stdout.write("")

    def _interactive_mode(self, endpoints):
        """Enter interactive inspection mode"""
        self.stdout.write(
            self.style.SUCCESS("\nEntering interactive mode (Ctrl+C to exit)...\n")
        )

        try:
            while True:
                self.stdout.write("Select an endpoint to inspect (or 'q' to quit):")
                for i, endpoint in enumerate(endpoints, 1):
                    self.stdout.write(f"  {i}. {endpoint.view_class.__name__} ({endpoint.path})")

                choice = input("\n> ").strip().lower()

                if choice == "q":
                    break

                try:
                    idx = int(choice) - 1
                    if 0 <= idx < len(endpoints):
                        self._inspect_endpoint(endpoints[idx])
                    else:
                        self.stdout.write(self.style.ERROR("Invalid selection."))
                except ValueError:
                    self.stdout.write(self.style.ERROR("Please enter a number or 'q'."))

        except KeyboardInterrupt:
            self.stdout.write(self.style.SUCCESS("\n\nGoodbye!"))

    def _inspect_endpoint(self, endpoint):
        """Inspect a single endpoint in detail"""
        self.stdout.write(
            self.style.SUCCESS(f"\n=== {endpoint.view_class.__name__} ===\n")
        )
        self.stdout.write(f"Path: {endpoint.path}")
        self.stdout.write(f"Type: {'ViewSet' if endpoint.is_viewset else 'APIView'}")
        self.stdout.write(f"Methods: {', '.join(endpoint.http_methods)}\n")

        # Display serializer schema if available
        if hasattr(endpoint.view_class, "serializer_class"):
            try:
                schema_converter = SchemaConverter()
                serializer = endpoint.view_class.serializer_class()
                schema = schema_converter.serialize_to_schema(serializer)

                self.stdout.write(self.style.HTTP_INFO("Request Schema:"))
                self.stdout.write(json.dumps(schema, indent=2))
            except Exception as e:
                self.stdout.write(self.style.ERROR(f"Schema error: {e}"))

        self.stdout.write("")
