"""
Validate UI Schema Alignment.

Django management command to validate that Pydantic UI schemas
in lightwave-core match TypeScript interfaces in lightwave-ui.

Usage:
    python manage.py validate_ui
    python manage.py validate_ui --strict
    python manage.py validate_ui --json
    python manage.py validate_ui --ts-path /path/to/lightwave-ui/src
"""

from __future__ import annotations

import json
import sys
from pathlib import Path

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


class Command(BaseCommand):
    """Validate Pydantic UI schemas against TypeScript interfaces."""

    help = "Validate that Pydantic UI schemas in lightwave-core match TypeScript interfaces in lightwave-ui"

    def add_arguments(self, parser) -> None:
        parser.add_argument(
            "--strict",
            action="store_true",
            help="Fail on warnings as well as errors",
        )
        parser.add_argument(
            "--json",
            action="store_true",
            help="Output report as JSON",
        )
        parser.add_argument(
            "--ts-path",
            type=str,
            default=None,
            help="Path to lightwave-ui/src directory (auto-detected if not specified)",
        )
        parser.add_argument(
            "--summary-only",
            action="store_true",
            help="Only show summary, not individual issues",
        )
        parser.add_argument(
            "--category",
            type=str,
            default=None,
            help="Filter issues by category (missing_pydantic, type_mismatch, etc.)",
        )

    def handle(self, *args, **options) -> None:
        try:
            from lightwave.schema.ui_alignment import UIAlignmentChecker
        except ImportError as e:
            raise CommandError(
                f"Could not import UI alignment checker: {e}\n"
                "Make sure lightwave-core is installed with all dependencies."
            ) from e

        # Configure checker
        ts_path = None
        if options["ts_path"]:
            ts_path = Path(options["ts_path"])
            if not ts_path.exists():
                raise CommandError(f"TypeScript path does not exist: {ts_path}")

        try:
            checker = UIAlignmentChecker(ts_src_path=ts_path)
            report = checker.check_all()
        except FileNotFoundError as e:
            raise CommandError(f"Could not locate lightwave-ui: {e}\nUse --ts-path to specify the location.") from e
        except Exception as e:
            raise CommandError(f"Error during validation: {e}") from e

        # Filter by category if specified
        if options["category"]:
            report.issues = [i for i in report.issues if i.category == options["category"]]

        # Output results
        if options["json"]:
            self._output_json(report)
        elif options["summary_only"]:
            self._output_summary(report)
        else:
            self._output_full(report)

        # Determine exit code
        if not report.is_aligned:
            sys.exit(1)
        if options["strict"] and report.warning_count > 0:
            sys.exit(1)

    def _output_json(self, report) -> None:
        """Output report as JSON."""
        self.stdout.write(json.dumps(report.to_dict(), indent=2))

    def _output_summary(self, report) -> None:
        """Output summary only."""
        status = self.style.SUCCESS("ALIGNED") if report.is_aligned else self.style.ERROR("NOT ALIGNED")

        self.stdout.write(f"\nUI Schema Alignment: {status}")
        self.stdout.write(f"  TypeScript interfaces: {report.ts_interfaces_count}")
        self.stdout.write(f"  Pydantic schemas: {report.pydantic_schemas_count}")
        self.stdout.write(f"  Matched: {report.matched_count}")
        self.stdout.write(f"  Errors: {report.error_count}")
        self.stdout.write(f"  Warnings: {report.warning_count}")

    def _output_full(self, report) -> None:
        """Output full report."""
        self._output_summary(report)

        if not report.issues:
            self.stdout.write(self.style.SUCCESS("\nNo issues found!"))
            return

        self.stdout.write("\nIssues:")

        # Group by category
        by_category: dict[str, list] = {}
        for issue in report.issues:
            by_category.setdefault(issue.category, []).append(issue)

        for category, issues in sorted(by_category.items()):
            style = self.style.ERROR if issues[0].severity == "error" else self.style.WARNING
            self.stdout.write(f"\n  {style(category.upper())} ({len(issues)})")

            for issue in issues[:20]:  # Limit display
                icon = "E" if issue.severity == "error" else "W"
                prop = f".{issue.property_name}" if issue.property_name else ""
                self.stdout.write(f"    [{icon}] {issue.interface_name}{prop}")
                self.stdout.write(f"        {issue.message}")

            if len(issues) > 20:
                self.stdout.write(f"    ... and {len(issues) - 20} more")
