"""
Management command to list all SST specification files.

Usage:
    # List all specs
    python manage.py spec_list

    # Filter by type
    python manage.py spec_list --type user_flows

    # Filter by domain
    python manage.py spec_list --domain auth

    # Show compliance info
    python manage.py spec_list --compliance
"""

from pathlib import Path
from typing import Any

import yaml
from django.core.management.base import BaseCommand

SST_ROOT = Path(__file__).parents[2] / "definitions"

# Spec types that contain testable specifications
SPEC_TYPES = {
    "user_flows": "User journey definitions",
    "routes": "URL routing specifications",
    "webhooks": "Webhook payload definitions",
    "sockets": "WebSocket message definitions",
    "workflows": "Agentic workflow definitions",
}


class Command(BaseCommand):
    """List all SST specification files with optional filtering."""

    help = "List all SST specifications (user_flows, routes, webhooks, sockets)"

    def add_arguments(self, parser: Any) -> None:
        parser.add_argument(
            "--type",
            type=str,
            choices=list(SPEC_TYPES.keys()),
            help=f"Filter by type: {', '.join(SPEC_TYPES.keys())}",
        )
        parser.add_argument(
            "--domain",
            type=str,
            help="Filter by domain (e.g., auth, payments, admin)",
        )
        parser.add_argument(
            "--compliance",
            action="store_true",
            help="Show compliance status for each spec",
        )

    def handle(self, *args: Any, **options: Any) -> None:
        spec_type = options.get("type")
        domain = options.get("domain")
        show_compliance = options.get("compliance", False)
        verbosity = options.get("verbosity", 1)

        # Determine which types to list
        if spec_type:
            types_to_list = [spec_type]
        else:
            types_to_list = list(SPEC_TYPES.keys())

        total_specs = 0
        total_compliant = 0

        for stype in types_to_list:
            specs = self._find_specs(stype, domain)
            if not specs:
                continue

            self.stdout.write(f"\n{SPEC_TYPES.get(stype, stype)} ({stype}/):")
            self.stdout.write("-" * 50)

            for spec_path in sorted(specs):
                rel_path = spec_path.relative_to(SST_ROOT)
                total_specs += 1

                # Load spec metadata
                meta = self._load_spec_meta(spec_path)
                version = meta.get("version", "?")
                component = meta.get("component", "")

                if show_compliance:
                    is_compliant = self._check_compliance(spec_path)
                    total_compliant += 1 if is_compliant else 0
                    status = self.style.SUCCESS("✓") if is_compliant else self.style.ERROR("✗")
                    self.stdout.write(f"  {status} {rel_path} (v{version})")
                else:
                    self.stdout.write(f"  {rel_path} (v{version})")

                if verbosity > 1 and component:
                    self.stdout.write(f"      Component: {component}")

        # Summary
        self.stdout.write("\n" + "=" * 50)
        self.stdout.write(f"Total: {total_specs} specification(s)")
        if show_compliance:
            pct = (total_compliant / total_specs * 100) if total_specs else 0
            self.stdout.write(f"Compliant: {total_compliant}/{total_specs} ({pct:.0f}%)")

    def _find_specs(self, spec_type: str, domain: str | None) -> list[Path]:
        """Find all YAML specs of the given type, optionally filtered by domain."""
        type_dir = SST_ROOT / spec_type
        if not type_dir.exists():
            # Check if it's a top-level file
            top_level = SST_ROOT / f"{spec_type}.yaml"
            if top_level.exists():
                return [top_level]
            return []

        specs = []
        for yaml_file in type_dir.rglob("*.yaml"):
            if yaml_file.name.startswith("_"):
                continue  # Skip index files

            if domain:
                # Check if domain matches path or content
                rel_path = yaml_file.relative_to(type_dir)
                if domain not in str(rel_path):
                    # Check file content for domain
                    try:
                        data = yaml.safe_load(yaml_file.read_text())
                        meta = data.get("_meta", {})
                        if domain not in meta.get("domain", ""):
                            continue
                    except Exception:
                        continue

            specs.append(yaml_file)

        return specs

    def _load_spec_meta(self, spec_path: Path) -> dict[str, Any]:
        """Load _meta from a spec file."""
        try:
            data = yaml.safe_load(spec_path.read_text())
            return data.get("_meta", {})
        except Exception:
            return {}

    def _check_compliance(self, spec_path: Path) -> bool:
        """Check if a spec has implementation coverage."""
        # For now, check if spec has required _meta fields
        meta = self._load_spec_meta(spec_path)
        required = ["version", "component"]
        return all(meta.get(f) for f in required)
