"""
Management command for comprehensive schema consistency validation.

This command provides a single entry point for all validation needs:
- Self-format validation (against meta/self-format.yaml)
- Cross-reference validation (domains, layouts, user_types, etc.)
- Field options coverage (all referenced options exist)
- Pydantic-YAML coverage (all definitions have models)
- Deployment cross-reference validation

Usage:
    # Run all validations
    python manage.py validate_consistency

    # Run specific validation suite
    python manage.py validate_consistency --suite self-format
    python manage.py validate_consistency --suite cross-refs
    python manage.py validate_consistency --suite coverage

    # Verbose output with suggestions
    python manage.py validate_consistency -v 2

    # Exit with error code on warnings (strict mode)
    python manage.py validate_consistency --strict

    # JSON output for CI/CD
    python manage.py validate_consistency --format json
"""

from __future__ import annotations

import json
import re
from dataclasses import dataclass, field
from enum import Enum
from pathlib import Path
from typing import Any

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

from lightwave.schema.pydantic.core.validators.field_options import FieldOptions
from lightwave.schema.validation.cross_validator import CrossReferenceValidator


class ValidationSeverity(str, Enum):
    """Severity levels for validation issues."""

    ERROR = "error"
    WARNING = "warning"
    INFO = "info"


@dataclass
class ValidationResult:
    """A single validation result."""

    file: str
    rule: str
    severity: ValidationSeverity
    message: str
    location: str = ""
    value: str = ""
    suggestion: str = ""


@dataclass
class SuiteReport:
    """Report for a validation suite."""

    name: str
    results: list[ValidationResult] = field(default_factory=list)
    stats: dict[str, int] = field(default_factory=dict)

    @property
    def error_count(self) -> int:
        return sum(1 for r in self.results if r.severity == ValidationSeverity.ERROR)

    @property
    def warning_count(self) -> int:
        return sum(1 for r in self.results if r.severity == ValidationSeverity.WARNING)

    @property
    def is_valid(self) -> bool:
        return self.error_count == 0


@dataclass
class ConsistencyReport:
    """Full consistency validation report."""

    suites: dict[str, SuiteReport] = field(default_factory=dict)

    @property
    def total_errors(self) -> int:
        return sum(s.error_count for s in self.suites.values())

    @property
    def total_warnings(self) -> int:
        return sum(s.warning_count for s in self.suites.values())

    @property
    def is_valid(self) -> bool:
        return self.total_errors == 0

    def to_dict(self) -> dict[str, Any]:
        return {
            "valid": self.is_valid,
            "total_errors": self.total_errors,
            "total_warnings": self.total_warnings,
            "suites": {
                name: {
                    "valid": suite.is_valid,
                    "error_count": suite.error_count,
                    "warning_count": suite.warning_count,
                    "stats": suite.stats,
                    "results": [
                        {
                            "file": r.file,
                            "rule": r.rule,
                            "severity": r.severity.value,
                            "message": r.message,
                            "location": r.location,
                            "value": r.value,
                            "suggestion": r.suggestion,
                        }
                        for r in suite.results
                    ],
                }
                for name, suite in self.suites.items()
            },
        }


class SelfFormatValidator:
    """
    Validates YAML files against meta/self-format.yaml rules.

    Rules checked:
    - header_present: File has ASCII-boxed header comment
    - meta_version: _meta.version is valid semver
    - definitions_documented: All definitions have descriptions
    - no_orphan_refs: All $ref targets exist
    - consistent_naming: Names follow conventions
    """

    def __init__(self, schema_dir: Path | None = None):
        self.schema_dir = schema_dir or Path(__file__).parents[2] / "definitions"
        self._self_format: dict[str, Any] | None = None

    def _load_self_format(self) -> dict[str, Any]:
        """Load the self-format meta-schema."""
        if self._self_format is None:
            meta_path = self.schema_dir / "meta" / "self-format.yaml"
            if meta_path.exists():
                with open(meta_path) as f:
                    self._self_format = yaml.safe_load(f) or {}
            else:
                self._self_format = {}
        return self._self_format

    def validate_all(self) -> SuiteReport:
        """Validate all schema files against self-format rules."""
        report = SuiteReport(name="self-format")
        stats = {
            "files_checked": 0,
            "headers_valid": 0,
            "meta_valid": 0,
            "naming_issues": 0,
        }

        # Get all YAML files in definitions/
        yaml_files = list(self.schema_dir.glob("*.yaml"))
        yaml_files.extend(self.schema_dir.glob("**/*.yaml"))

        for yaml_path in yaml_files:
            # Skip meta folder files from validation (they define the rules)
            if "meta" in yaml_path.parts:
                continue

            stats["files_checked"] += 1
            rel_path = yaml_path.relative_to(self.schema_dir)

            try:
                with open(yaml_path) as f:
                    content = f.read()
                    f.seek(0)
                    data = yaml.safe_load(f) or {}
            except yaml.YAMLError as e:
                report.results.append(
                    ValidationResult(
                        file=str(rel_path),
                        rule="yaml_syntax",
                        severity=ValidationSeverity.ERROR,
                        message=f"Invalid YAML syntax: {e}",
                    )
                )
                continue

            # Rule: header_present
            if self._check_header(content):
                stats["headers_valid"] += 1
            else:
                report.results.append(
                    ValidationResult(
                        file=str(rel_path),
                        rule="header_present",
                        severity=ValidationSeverity.WARNING,
                        message="File missing ASCII-boxed header comment",
                        suggestion="Add header block per meta/self-format.yaml",
                    )
                )

            # Rule: meta_version
            meta = data.get("_meta", {})
            if meta:
                version = meta.get("version", "")
                if self._check_version(version):
                    stats["meta_valid"] += 1
                else:
                    report.results.append(
                        ValidationResult(
                            file=str(rel_path),
                            rule="meta_version",
                            severity=ValidationSeverity.ERROR,
                            message=f"Invalid version format: '{version}'",
                            location="_meta.version",
                            value=str(version),
                            suggestion="Use semver format: MAJOR.MINOR or MAJOR.MINOR.PATCH",
                        )
                    )
            else:
                report.results.append(
                    ValidationResult(
                        file=str(rel_path),
                        rule="meta_version",
                        severity=ValidationSeverity.WARNING,
                        message="Missing _meta section",
                        suggestion="Add _meta with version and description",
                    )
                )

            # Rule: consistent_naming (file name)
            if not self._check_file_naming(yaml_path.stem):
                stats["naming_issues"] += 1
                report.results.append(
                    ValidationResult(
                        file=str(rel_path),
                        rule="consistent_naming",
                        severity=ValidationSeverity.WARNING,
                        message=f"File name '{yaml_path.stem}' doesn't follow convention",
                        suggestion="Use lowercase with hyphens: example-file.yaml",
                    )
                )

            # Rule: definitions_documented
            self._check_definitions_documented(data, str(rel_path), report)

            # Rule: no_orphan_refs
            self._check_orphan_refs(data, str(rel_path), report)

        report.stats = stats
        return report

    def _check_header(self, content: str) -> bool:
        """Check if file has ASCII-boxed header comment."""
        # Header should start with # ===...
        lines = content.split("\n")
        for line in lines[:5]:  # Check first 5 lines
            if line.startswith("# ====="):
                return True
        return False

    def _check_version(self, version: Any) -> bool:
        """Check if version is valid semver."""
        if not isinstance(version, str):
            return False
        return bool(re.match(r"^\d+\.\d+(\.\d+)?$", version))

    def _check_file_naming(self, stem: str) -> bool:
        """Check if file name follows convention."""
        # Allow __index for directory indexes
        if stem == "__index":
            return True
        return bool(re.match(r"^[a-z][a-z0-9-]*$", stem))

    def _check_definitions_documented(self, data: dict[str, Any], file: str, report: SuiteReport) -> None:
        """Check that definitions have descriptions."""
        # Look for common definition patterns
        def_keys = [
            "definitions",
            "layouts",
            "tenants",
            "routes",
            "user_flows",
            "pages",
            "features",
        ]

        for key in def_keys:
            if key in data and isinstance(data[key], dict):
                for def_name, def_data in data[key].items():
                    if isinstance(def_data, dict):
                        if not def_data.get("description"):
                            report.results.append(
                                ValidationResult(
                                    file=file,
                                    rule="definitions_documented",
                                    severity=ValidationSeverity.INFO,
                                    message=f"Definition '{def_name}' missing description",
                                    location=f"{key}.{def_name}",
                                    suggestion="Add a 'description' field",
                                )
                            )

    def _check_orphan_refs(self, data: dict[str, Any], file: str, report: SuiteReport) -> None:
        """Check for orphan $ref references."""
        refs = self._collect_refs(data)
        for ref_path, ref_value in refs:
            if ref_value.startswith("#/"):
                # Internal reference
                target_path = ref_value[2:].split("/")
                if not self._resolve_internal_ref(data, target_path):
                    report.results.append(
                        ValidationResult(
                            file=file,
                            rule="no_orphan_refs",
                            severity=ValidationSeverity.ERROR,
                            message=f"Orphan reference: '{ref_value}' not found",
                            location=ref_path,
                            value=ref_value,
                        )
                    )

    def _collect_refs(self, data: Any, path: str = "") -> list[tuple[str, str]]:
        """Recursively collect all $ref values."""
        refs = []
        if isinstance(data, dict):
            for key, value in data.items():
                current_path = f"{path}.{key}" if path else key
                if key == "$ref" and isinstance(value, str):
                    refs.append((current_path, value))
                else:
                    refs.extend(self._collect_refs(value, current_path))
        elif isinstance(data, list):
            for i, item in enumerate(data):
                refs.extend(self._collect_refs(item, f"{path}[{i}]"))
        return refs

    def _resolve_internal_ref(self, data: dict[str, Any], path: list[str]) -> bool:
        """Try to resolve an internal reference path."""
        current = data
        for segment in path:
            if isinstance(current, dict) and segment in current:
                current = current[segment]
            else:
                return False
        return True


class CoverageValidator:
    """
    Validates coverage between YAML definitions and Pydantic models.

    Checks:
    - All field_options references exist in field_options.yaml
    - All YAML definition files have corresponding Pydantic models
    - All layouts in layouts.yaml have Pydantic coverage
    """

    def __init__(self, schema_dir: Path | None = None):
        self.schema_dir = schema_dir or Path(__file__).parents[2] / "definitions"
        self.pydantic_dir = Path(__file__).parents[2] / "pydantic"

    def validate_all(self) -> SuiteReport:
        """Run all coverage validations."""
        report = SuiteReport(name="coverage")
        stats = {
            "field_options_defined": 0,
            "field_options_valid": 0,
            "pydantic_models": 0,
            "yaml_definitions": 0,
        }

        # Validate field options
        self._validate_field_options(report, stats)

        # Validate Pydantic coverage
        self._validate_pydantic_coverage(report, stats)

        report.stats = stats
        return report

    def _validate_field_options(self, report: SuiteReport, stats: dict[str, int]) -> None:
        """Validate field_options.yaml coverage."""
        try:
            all_fields = FieldOptions.get_all_field_names()
            stats["field_options_defined"] = len(all_fields)

            # Check each field has valid structure
            for field_name in all_fields:
                try:
                    values = FieldOptions.get_values(field_name)
                    if values:
                        stats["field_options_valid"] += 1
                    else:
                        report.results.append(
                            ValidationResult(
                                file="field_options.yaml",
                                rule="field_options_coverage",
                                severity=ValidationSeverity.WARNING,
                                message=f"Field '{field_name}' has no options defined",
                                location=field_name,
                            )
                        )
                except Exception as e:
                    report.results.append(
                        ValidationResult(
                            file="field_options.yaml",
                            rule="field_options_coverage",
                            severity=ValidationSeverity.ERROR,
                            message=f"Error loading field '{field_name}': {e}",
                            location=field_name,
                        )
                    )
        except FileNotFoundError:
            report.results.append(
                ValidationResult(
                    file="field_options.yaml",
                    rule="field_options_coverage",
                    severity=ValidationSeverity.ERROR,
                    message="field_options.yaml not found",
                    suggestion="Create definitions/field_options.yaml",
                )
            )

    def _validate_pydantic_coverage(self, report: SuiteReport, stats: dict[str, int]) -> None:
        """Check Pydantic model coverage for YAML definitions."""
        # Count YAML definitions
        yaml_files = list(self.schema_dir.glob("*.yaml"))
        stats["yaml_definitions"] = len(yaml_files)

        # Count Pydantic models
        pydantic_models_dir = self.pydantic_dir / "models"
        if pydantic_models_dir.exists():
            py_files = list(pydantic_models_dir.glob("*.py"))
            stats["pydantic_models"] = len([f for f in py_files if f.stem != "__init__"])

        # Check for specific coverage gaps
        expected_models = [
            ("layouts.yaml", "layouts.py"),
            ("email.yaml", "emails.py"),
            ("domains.yaml", "domains.py"),
        ]

        for yaml_file, py_file in expected_models:
            yaml_path = self.schema_dir / yaml_file
            py_path = pydantic_models_dir / py_file

            if yaml_path.exists() and not py_path.exists():
                report.results.append(
                    ValidationResult(
                        file=yaml_file,
                        rule="pydantic_coverage",
                        severity=ValidationSeverity.INFO,
                        message=f"No Pydantic model for {yaml_file}",
                        suggestion=f"Create pydantic/models/{py_file}",
                    )
                )


class UserFlowsValidator:
    """
    Validates user_flows nested directory structure and cross-references.

    Checks:
    - All flows listed in __index.yaml domains.flows exist as files
    - All flow files in directories are registered in __index.yaml
    - Flow files have required meta blocks
    - Flow references (entry_points, api_endpoints) are valid
    """

    def __init__(self, schema_dir: Path | None = None):
        self.schema_dir = schema_dir or Path(__file__).parents[2] / "definitions"
        self.user_flows_dir = self.schema_dir / "user_flows"

    def validate_all(self) -> SuiteReport:
        """Validate user_flows nested directory structure."""
        report = SuiteReport(name="user-flows")
        stats = {
            "domains_defined": 0,
            "flows_registered": 0,
            "flow_files_found": 0,
            "orphan_files": 0,
            "missing_flows": 0,
        }

        if not self.user_flows_dir.exists():
            report.results.append(
                ValidationResult(
                    file="user_flows/",
                    rule="directory_exists",
                    severity=ValidationSeverity.WARNING,
                    message="user_flows directory not found",
                    suggestion="Create definitions/user_flows/",
                )
            )
            report.stats = stats
            return report

        # Load __index.yaml
        index_path = self.user_flows_dir / "__index.yaml"
        if not index_path.exists():
            report.results.append(
                ValidationResult(
                    file="user_flows/__index.yaml",
                    rule="index_exists",
                    severity=ValidationSeverity.ERROR,
                    message="__index.yaml not found in user_flows",
                    suggestion="Create user_flows/__index.yaml",
                )
            )
            report.stats = stats
            return report

        with open(index_path) as f:
            index_data = yaml.safe_load(f) or {}

        # Collect all registered flows from domains
        registered_flows: set[str] = set()
        domains = index_data.get("domains", {})
        stats["domains_defined"] = len(domains)

        for _domain_name, domain_data in domains.items():
            if isinstance(domain_data, dict):
                flows = domain_data.get("flows", [])
                for flow_path in flows:
                    registered_flows.add(flow_path)

        stats["flows_registered"] = len(registered_flows)

        # Find all actual flow files
        actual_files: set[str] = set()
        for yaml_path in self.user_flows_dir.glob("**/*.yaml"):
            if yaml_path.name == "__index.yaml":
                continue
            # Convert to relative path format matching flows (e.g., "auth/signup")
            rel_path = yaml_path.relative_to(self.user_flows_dir)
            flow_id = str(rel_path.with_suffix("")).replace("\\", "/")
            actual_files.add(flow_id)

        stats["flow_files_found"] = len(actual_files)

        # Check for missing flows (registered but no file)
        missing = registered_flows - actual_files
        stats["missing_flows"] = len(missing)
        for flow_path in sorted(missing):
            report.results.append(
                ValidationResult(
                    file="user_flows/__index.yaml",
                    rule="flow_file_exists",
                    severity=ValidationSeverity.ERROR,
                    message=f"Registered flow '{flow_path}' has no corresponding file",
                    location="domains.*.flows",
                    value=flow_path,
                    suggestion=f"Create user_flows/{flow_path}.yaml",
                )
            )

        # Check for orphan files (file exists but not registered)
        orphans = actual_files - registered_flows
        stats["orphan_files"] = len(orphans)
        for flow_path in sorted(orphans):
            report.results.append(
                ValidationResult(
                    file=f"user_flows/{flow_path}.yaml",
                    rule="flow_registered",
                    severity=ValidationSeverity.WARNING,
                    message="Flow file exists but is not registered in __index.yaml",
                    value=flow_path,
                    suggestion=f"Add '{flow_path}' to appropriate domain in __index.yaml",
                )
            )

        # Validate each flow file has required structure
        for flow_path in actual_files:
            yaml_path = self.user_flows_dir / f"{flow_path}.yaml"
            self._validate_flow_file(yaml_path, flow_path, report)

        # Validate api_endpoints references
        self._validate_api_endpoints(index_data, report)

        report.stats = stats
        return report

    def _validate_flow_file(self, yaml_path: Path, flow_id: str, report: SuiteReport) -> None:
        """Validate individual flow file structure."""
        try:
            with open(yaml_path) as f:
                data = yaml.safe_load(f) or {}

            # Check for _meta
            if "_meta" not in data:
                report.results.append(
                    ValidationResult(
                        file=f"user_flows/{flow_id}.yaml",
                        rule="flow_meta_required",
                        severity=ValidationSeverity.WARNING,
                        message="Flow file missing _meta section",
                        suggestion="Add _meta with version and description",
                    )
                )
            else:
                meta = data["_meta"]
                if not meta.get("version"):
                    report.results.append(
                        ValidationResult(
                            file=f"user_flows/{flow_id}.yaml",
                            rule="flow_version_required",
                            severity=ValidationSeverity.WARNING,
                            message="Flow _meta missing version",
                            location="_meta.version",
                        )
                    )

        except yaml.YAMLError as e:
            report.results.append(
                ValidationResult(
                    file=f"user_flows/{flow_id}.yaml",
                    rule="yaml_syntax",
                    severity=ValidationSeverity.ERROR,
                    message=f"Invalid YAML: {e}",
                )
            )

    def _validate_api_endpoints(self, index_data: dict[str, Any], report: SuiteReport) -> None:
        """Validate api_endpoints have valid structure."""
        api_endpoints = index_data.get("api_endpoints", {})

        for endpoint_name, endpoint_data in api_endpoints.items():
            if not isinstance(endpoint_data, dict):
                continue

            # Check required fields
            if not endpoint_data.get("path") and not endpoint_data.get("url_pattern"):
                report.results.append(
                    ValidationResult(
                        file="user_flows/__index.yaml",
                        rule="endpoint_path_required",
                        severity=ValidationSeverity.WARNING,
                        message=f"Endpoint '{endpoint_name}' missing path or url_pattern",
                        location=f"api_endpoints.{endpoint_name}",
                    )
                )

            # Check method is valid
            method = endpoint_data.get("method", "GET")
            valid_methods = {"GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"}
            if isinstance(method, list):
                for m in method:
                    if m.upper() not in valid_methods:
                        report.results.append(
                            ValidationResult(
                                file="user_flows/__index.yaml",
                                rule="endpoint_method_valid",
                                severity=ValidationSeverity.ERROR,
                                message=f"Invalid HTTP method: {m}",
                                location=f"api_endpoints.{endpoint_name}.method",
                                value=m,
                            )
                        )
            elif method.upper() not in valid_methods:
                report.results.append(
                    ValidationResult(
                        file="user_flows/__index.yaml",
                        rule="endpoint_method_valid",
                        severity=ValidationSeverity.ERROR,
                        message=f"Invalid HTTP method: {method}",
                        location=f"api_endpoints.{endpoint_name}.method",
                        value=method,
                    )
                )


class DeploymentCrossRefValidator:
    """
    Validates cross-references between deployment.yaml and platform workflows.

    Ensures deployment stages reference valid platform components and
    platform workflows reference valid deployment configurations.
    """

    def __init__(self, schema_dir: Path | None = None):
        self.schema_dir = schema_dir or Path(__file__).parents[2] / "definitions"

    def validate_all(self) -> SuiteReport:
        """Validate deployment ↔ platform cross-references."""
        report = SuiteReport(name="deployment-cross-refs")
        stats = {
            "deployment_stages": 0,
            "platform_workflows": 0,
            "cross_refs_valid": 0,
        }

        # Load deployment.yaml
        deployment_path = self.schema_dir / "deployment.yaml"
        if not deployment_path.exists():
            report.results.append(
                ValidationResult(
                    file="deployment.yaml",
                    rule="file_exists",
                    severity=ValidationSeverity.WARNING,
                    message="deployment.yaml not found",
                    suggestion="Create definitions/deployment.yaml",
                )
            )
            report.stats = stats
            return report

        with open(deployment_path) as f:
            deployment_data = yaml.safe_load(f) or {}

        # Count deployment stages
        stages = deployment_data.get("stages", {})
        stats["deployment_stages"] = len(stages)

        # Load platform workflows
        platform_dir = self.schema_dir / "user_flows" / "platform"
        platform_workflows: dict[str, Any] = {}
        if platform_dir.exists():
            for workflow_file in platform_dir.glob("*.yaml"):
                if workflow_file.stem != "__index":
                    with open(workflow_file) as f:
                        platform_workflows[workflow_file.stem] = yaml.safe_load(f) or {}

        stats["platform_workflows"] = len(platform_workflows)

        # Cross-validate: deployment stages should have platform workflow coverage
        for stage_name, stage_data in stages.items():
            if isinstance(stage_data, dict):
                # Check if stage references platform workflows
                requires_workflow = stage_data.get("requires_workflow")
                if requires_workflow and requires_workflow not in platform_workflows:
                    report.results.append(
                        ValidationResult(
                            file="deployment.yaml",
                            rule="deployment_workflow_ref",
                            severity=ValidationSeverity.WARNING,
                            message=f"Stage '{stage_name}' references missing workflow",
                            location=f"stages.{stage_name}.requires_workflow",
                            value=requires_workflow,
                            suggestion=f"Create user_flows/platform/{requires_workflow}.yaml",
                        )
                    )
                else:
                    stats["cross_refs_valid"] += 1

        # Cross-validate: platform workflows should reference valid deployment stages
        for workflow_name, workflow_data in platform_workflows.items():
            if isinstance(workflow_data, dict):
                deployment_stage = workflow_data.get("deployment_stage")
                if deployment_stage and deployment_stage not in stages:
                    report.results.append(
                        ValidationResult(
                            file=f"user_flows/platform/{workflow_name}.yaml",
                            rule="workflow_deployment_ref",
                            severity=ValidationSeverity.WARNING,
                            message="Workflow references missing deployment stage",
                            location="deployment_stage",
                            value=deployment_stage,
                            suggestion=f"Add '{deployment_stage}' to deployment.yaml stages",
                        )
                    )

        report.stats = stats
        return report


class Command(BaseCommand):
    help = "Comprehensive schema consistency validation"

    def add_arguments(self, parser):
        parser.add_argument(
            "--suite",
            type=str,
            choices=["all", "self-format", "cross-refs", "coverage", "deployment", "user-flows"],
            default="all",
            help="Validation suite to run (default: all)",
        )
        parser.add_argument(
            "--strict",
            action="store_true",
            help="Exit with error code on warnings",
        )
        parser.add_argument(
            "--format",
            type=str,
            choices=["text", "json"],
            default="text",
            help="Output format (default: text)",
        )

    def handle(self, *args, **options):
        suite = options.get("suite", "all")
        strict = options.get("strict", False)
        output_format = options.get("format", "text")
        verbosity = options.get("verbosity", 1)

        report = ConsistencyReport()

        # Run requested validation suites
        suites_to_run = []
        if suite == "all":
            suites_to_run = ["self-format", "cross-refs", "coverage", "user-flows", "deployment"]
        else:
            suites_to_run = [suite]

        for suite_name in suites_to_run:
            if suite_name == "self-format":
                validator = SelfFormatValidator()
                report.suites["self-format"] = validator.validate_all()

            elif suite_name == "cross-refs":
                validator = CrossReferenceValidator()
                cross_report = validator.validate_all()
                # Convert CrossReferenceReport to SuiteReport
                suite_report = SuiteReport(name="cross-refs")
                for issue in cross_report.issues:
                    suite_report.results.append(
                        ValidationResult(
                            file=issue.file,
                            rule=issue.issue_type,
                            severity=ValidationSeverity.ERROR,
                            message=issue.message,
                            location=issue.location,
                            value=issue.value,
                            suggestion=issue.suggestion or "",
                        )
                    )
                for warning in cross_report.warnings:
                    suite_report.results.append(
                        ValidationResult(
                            file=warning.file,
                            rule=warning.issue_type,
                            severity=ValidationSeverity.WARNING,
                            message=warning.message,
                            location=warning.location,
                            value=warning.value,
                            suggestion=warning.suggestion or "",
                        )
                    )
                suite_report.stats = cross_report.stats
                report.suites["cross-refs"] = suite_report

            elif suite_name == "coverage":
                validator = CoverageValidator()
                report.suites["coverage"] = validator.validate_all()

            elif suite_name == "user-flows":
                validator = UserFlowsValidator()
                report.suites["user-flows"] = validator.validate_all()

            elif suite_name == "deployment":
                validator = DeploymentCrossRefValidator()
                report.suites["deployment"] = validator.validate_all()

        # Output results
        if output_format == "json":
            self.stdout.write(json.dumps(report.to_dict(), indent=2))
        else:
            self._output_text(report, verbosity)

        # Exit code
        if not report.is_valid:
            raise CommandError(f"Validation failed: {report.total_errors} error(s)")
        elif strict and report.total_warnings > 0:
            raise CommandError(f"Validation warnings (strict mode): {report.total_warnings} warning(s)")

    def _output_text(self, report: ConsistencyReport, verbosity: int) -> None:
        """Output report in human-readable text format."""
        self.stdout.write("\n" + "=" * 60)
        self.stdout.write("SCHEMA CONSISTENCY VALIDATION REPORT")
        self.stdout.write("=" * 60 + "\n")

        for suite_name, suite_report in report.suites.items():
            self.stdout.write(f"\n📋 {suite_name.upper()}")
            self.stdout.write("-" * 40)

            # Stats
            if suite_report.stats:
                for stat_name, stat_value in suite_report.stats.items():
                    self.stdout.write(f"  {stat_name}: {stat_value}")

            # Results
            errors = [r for r in suite_report.results if r.severity == ValidationSeverity.ERROR]
            warnings = [r for r in suite_report.results if r.severity == ValidationSeverity.WARNING]
            infos = [r for r in suite_report.results if r.severity == ValidationSeverity.INFO]

            if errors:
                self.stdout.write(self.style.ERROR(f"\n  ❌ {len(errors)} Error(s):"))
                for result in errors:
                    self.stdout.write(self.style.ERROR(f"    • {result.file}"))
                    self.stdout.write(f"      [{result.rule}] {result.message}")
                    if result.location and verbosity > 1:
                        self.stdout.write(f"      Location: {result.location}")
                    if result.value and verbosity > 1:
                        self.stdout.write(f"      Value: {result.value}")
                    if result.suggestion and verbosity > 0:
                        self.stdout.write(self.style.WARNING(f"      💡 {result.suggestion}"))

            if warnings:
                self.stdout.write(self.style.WARNING(f"\n  ⚠️  {len(warnings)} Warning(s):"))
                for result in warnings:
                    self.stdout.write(self.style.WARNING(f"    • {result.file}"))
                    self.stdout.write(f"      [{result.rule}] {result.message}")
                    if result.suggestion and verbosity > 0:
                        self.stdout.write(f"      💡 {result.suggestion}")

            if infos and verbosity > 1:
                self.stdout.write(f"\n  ℹ️  {len(infos)} Info:")
                for result in infos:
                    self.stdout.write(f"    • {result.file}: {result.message}")

            if suite_report.is_valid and not warnings:
                self.stdout.write(self.style.SUCCESS("\n  ✅ All checks passed"))

        # Summary
        self.stdout.write("\n" + "=" * 60)
        self.stdout.write("SUMMARY")
        self.stdout.write("=" * 60)

        if report.is_valid:
            self.stdout.write(self.style.SUCCESS(f"\n✅ VALID - {len(report.suites)} suites passed"))
        else:
            self.stdout.write(self.style.ERROR(f"\n❌ INVALID - {report.total_errors} error(s)"))

        if report.total_warnings:
            self.stdout.write(self.style.WARNING(f"⚠️  {report.total_warnings} warning(s)"))

        self.stdout.write("")
