"""
Health check report formatting and data structures.

Provides structured reporting of health check results with multiple output formats.
"""


from __future__ import annotations

from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from typing import Any


class CheckStatus(Enum):
    """Status of a health check."""

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


@dataclass
class CheckResult:
    """
    Result of a single health check.

    Attributes:
        status: Status level (success, info, warning, error)
        message: Human-readable description of the check result
        recommendation: Optional suggestion for how to fix/improve (shown for warnings/errors)
        details: Optional additional context (list of strings)
        validator: Name of validator that produced this result
    """

    status: CheckStatus
    message: str
    recommendation: str | None = None
    details: list[str] | None = None
    validator: str = ""

    @classmethod
    def success(cls, message: str, validator: str = "") -> CheckResult:
        """Create a success result."""
        return cls(CheckStatus.SUCCESS, message, validator=validator)

    @classmethod
    def info(
        cls,
        message: str,
        recommendation: str | None = None,
        details: list[str] | None = None,
        validator: str = "",
    ) -> CheckResult:
        """Create an info result."""
        return cls(CheckStatus.INFO, message, recommendation, details, validator=validator)

    @classmethod
    def warning(
        cls,
        message: str,
        recommendation: str | None = None,
        details: list[str] | None = None,
        validator: str = "",
    ) -> CheckResult:
        """Create a warning result."""
        return cls(CheckStatus.WARNING, message, recommendation, details, validator=validator)

    @classmethod
    def error(
        cls,
        message: str,
        recommendation: str | None = None,
        details: list[str] | None = None,
        validator: str = "",
    ) -> CheckResult:
        """Create an error result."""
        return cls(CheckStatus.ERROR, message, recommendation, details, validator=validator)

    def is_problem(self) -> bool:
        """Check if this is a warning or error (vs success/info)."""
        return self.status in (CheckStatus.WARNING, CheckStatus.ERROR)


@dataclass
class ValidatorReport:
    """
    Report for a single validator's checks.

    Attributes:
        validator_name: Name of the validator
        results: List of check results from this validator
        duration_ms: How long the validator took to run
    """

    validator_name: str
    results: list[CheckResult] = field(default_factory=list)
    duration_ms: float = 0.0

    @property
    def passed_count(self) -> int:
        """Count of successful checks."""
        return sum(1 for r in self.results if r.status == CheckStatus.SUCCESS)

    @property
    def info_count(self) -> int:
        """Count of info messages."""
        return sum(1 for r in self.results if r.status == CheckStatus.INFO)

    @property
    def warning_count(self) -> int:
        """Count of warnings."""
        return sum(1 for r in self.results if r.status == CheckStatus.WARNING)

    @property
    def error_count(self) -> int:
        """Count of errors."""
        return sum(1 for r in self.results if r.status == CheckStatus.ERROR)

    @property
    def has_problems(self) -> bool:
        """Check if this validator found any warnings or errors."""
        return self.warning_count > 0 or self.error_count > 0

    @property
    def status_emoji(self) -> str:
        """Get emoji representing overall status."""
        if self.error_count > 0:
            return "❌"
        elif self.warning_count > 0:
            return "⚠️"
        elif self.info_count > 0:
            return "ℹ️"
        else:
            return "✅"


@dataclass
class HealthReport:
    """
    Complete health check report for a build.

    Attributes:
        validator_reports: Reports from each validator
        timestamp: When the health check was run
        build_stats: Optional build statistics
    """

    validator_reports: list[ValidatorReport] = field(default_factory=list)
    timestamp: datetime = field(default_factory=datetime.now)
    build_stats: dict[str, Any] | None = None

    @property
    def total_passed(self) -> int:
        """Total successful checks across all validators."""
        return sum(r.passed_count for r in self.validator_reports)

    @property
    def total_info(self) -> int:
        """Total info messages across all validators."""
        return sum(r.info_count for r in self.validator_reports)

    @property
    def total_warnings(self) -> int:
        """Total warnings across all validators."""
        return sum(r.warning_count for r in self.validator_reports)

    @property
    def total_errors(self) -> int:
        """Total errors across all validators."""
        return sum(r.error_count for r in self.validator_reports)

    @property
    def total_checks(self) -> int:
        """Total number of checks run."""
        return self.total_passed + self.total_info + self.total_warnings + self.total_errors

    def has_errors(self) -> bool:
        """Check if any errors were found."""
        return self.total_errors > 0

    def has_warnings(self) -> bool:
        """Check if any warnings were found."""
        return self.total_warnings > 0

    def has_problems(self) -> bool:
        """Check if any errors or warnings were found."""
        return self.has_errors() or self.has_warnings()

    def build_quality_score(self) -> int:
        """
        Calculate build quality score (0-100).

        Formula:
        - Each passed check: +1 point
        - Each info: +0.8 points
        - Each warning: +0.5 points
        - Each error: +0 points

        Returns:
            Score from 0-100 (100 = perfect)
        """
        if self.total_checks == 0:
            return 100

        points = (
            self.total_passed * 1.0
            + self.total_info * 0.8
            + self.total_warnings * 0.5
            + self.total_errors * 0.0
        )

        return int((points / self.total_checks) * 100)

    def quality_rating(self) -> str:
        """Get quality rating based on score."""
        score = self.build_quality_score()

        if score >= 95:
            return "Excellent"
        elif score >= 85:
            return "Good"
        elif score >= 70:
            return "Fair"
        else:
            return "Needs Improvement"

    def format_console(self, mode: str = "auto", verbose: bool = False) -> str:
        """
        Format report for console output.

        Args:
            mode: Display mode - "auto", "quiet", "normal", "verbose"
                  auto = quiet if no problems, normal if warnings/errors
            verbose: Legacy parameter, sets mode to "verbose"

        Returns:
            Formatted string ready to print
        """
        # Handle legacy verbose parameter
        if verbose:
            mode = "verbose"

        # Auto-detect mode based on results
        if mode == "auto":
            mode = "quiet" if not self.has_problems() else "normal"

        if mode == "quiet":
            return self._format_quiet()
        elif mode == "verbose":
            return self._format_verbose()
        else:  # normal
            return self._format_normal()

    def _format_quiet(self) -> str:
        """
        Minimal output - perfect builds get one line, problems shown clearly.
        """
        lines = []

        # Perfect build - just success message
        if not self.has_problems():
            score = self.build_quality_score()
            return f"✓ Build complete. All health checks passed (quality: {score}%)\n"

        # Has problems - show them
        lines.append("")

        # Group by validator, only show problems
        for vr in self.validator_reports:
            if not vr.has_problems:
                continue

            # Show validator name with problem count
            problem_count = vr.warning_count + vr.error_count
            emoji = "❌" if vr.error_count > 0 else "⚠️"
            lines.append(f"{emoji} {vr.validator_name} ({problem_count} issue(s)):")

            # Show problem messages
            for result in vr.results:
                if result.is_problem():
                    lines.append(f"   • {result.message}")

                    # Show recommendation
                    if result.recommendation:
                        lines.append(f"     💡 {result.recommendation}")

                    # Show first 3 details
                    if result.details:
                        for detail in result.details[:3]:
                            lines.append(f"        - {detail}")
                        if len(result.details) > 3:
                            remaining = len(result.details) - 3
                            lines.append(f"        ... and {remaining} more")

            lines.append("")  # Blank line between validators

        # Summary
        score = self.build_quality_score()
        rating = self.quality_rating()
        summary_parts = []

        if self.total_errors > 0:
            summary_parts.append(f"{self.total_errors} error(s)")
        if self.total_warnings > 0:
            summary_parts.append(f"{self.total_warnings} warning(s)")

        lines.append(f"Build Quality: {score}% ({rating}) · {', '.join(summary_parts)}")
        lines.append("")

        return "\n".join(lines)

    def _format_normal(self) -> str:
        """
        Balanced output - show all validators but only problem details.
        """
        lines = []

        lines.append("\n🏥 Health Check Summary")
        lines.append("━" * 60)
        lines.append("")

        # Show all validators with status
        for vr in self.validator_reports:
            status_line = f"{vr.status_emoji} {vr.validator_name:<20}"

            if vr.error_count > 0:
                status_line += f" {vr.error_count} error(s)"
            elif vr.warning_count > 0:
                status_line += f" {vr.warning_count} warning(s)"
            elif vr.info_count > 0:
                status_line += f" {vr.info_count} info"
            else:
                status_line += " passed"

            lines.append(status_line)

            # Show problems only (not success messages)
            for result in vr.results:
                if result.is_problem():
                    lines.append(f"   • {result.message}")
                    if result.recommendation:
                        lines.append(f"     💡 {result.recommendation}")
                    if result.details:
                        for detail in result.details[:3]:
                            lines.append(f"        - {detail}")
                        if len(result.details) > 3:
                            lines.append(f"        ... and {len(result.details) - 3} more")

        # Summary
        lines.append("")
        lines.append("━" * 60)
        lines.append(
            f"Summary: {self.total_passed} passed, {self.total_warnings} warnings, {self.total_errors} errors"
        )

        score = self.build_quality_score()
        rating = self.quality_rating()
        lines.append(f"Build Quality: {score}% ({rating})")
        lines.append("")

        return "\n".join(lines)

    def _format_verbose(self) -> str:
        """
        Full audit trail - show everything including successes.
        """
        lines = []

        # Header
        lines.append("\n🏥 Health Check Report")
        lines.append("━" * 60)
        lines.append("")

        # Validator results
        for vr in self.validator_reports:
            # Status line
            status_line = f"{vr.status_emoji} {vr.validator_name:<20}"

            if vr.error_count > 0:
                status_line += f" {vr.error_count} error(s)"
            elif vr.warning_count > 0:
                status_line += f" {vr.warning_count} warning(s)"
            elif vr.info_count > 0:
                status_line += f" {vr.info_count} info"
            elif vr.passed_count > 0:
                status_line += f" {vr.passed_count} check(s) passed"

            lines.append(status_line)

            # Show all results in verbose mode
            for result in vr.results:
                # Indent the message
                lines.append(f"   • {result.message}")

                # Show recommendation if present
                if result.recommendation:
                    lines.append(f"     💡 {result.recommendation}")

                # Show details if present (limit to first 3)
                if result.details:
                    for detail in result.details[:3]:
                        lines.append(f"        - {detail}")
                    if len(result.details) > 3:
                        lines.append(f"        ... and {len(result.details) - 3} more")

        # Summary
        lines.append("")
        lines.append("━" * 60)
        lines.append(
            f"Summary: {self.total_passed} passed, {self.total_warnings} warnings, {self.total_errors} errors"
        )

        score = self.build_quality_score()
        rating = self.quality_rating()
        lines.append(f"Build Quality: {score}% ({rating})")

        # Build stats if available
        if self.build_stats:
            build_time = self.build_stats.get("build_time_ms", 0) / 1000
            lines.append(f"Build Time: {build_time:.2f}s")

        lines.append("")

        return "\n".join(lines)

    def format_json(self) -> dict[str, Any]:
        """
        Format report as JSON-serializable dictionary.

        Returns:
            Dictionary suitable for json.dumps()
        """
        return {
            "timestamp": self.timestamp.isoformat(),
            "summary": {
                "total_checks": self.total_checks,
                "passed": self.total_passed,
                "info": self.total_info,
                "warnings": self.total_warnings,
                "errors": self.total_errors,
                "quality_score": self.build_quality_score(),
                "quality_rating": self.quality_rating(),
            },
            "validators": [
                {
                    "name": vr.validator_name,
                    "duration_ms": vr.duration_ms,
                    "summary": {
                        "passed": vr.passed_count,
                        "info": vr.info_count,
                        "warnings": vr.warning_count,
                        "errors": vr.error_count,
                    },
                    "results": [
                        {
                            "status": r.status.value,
                            "message": r.message,
                            "recommendation": r.recommendation,
                            "details": r.details,
                        }
                        for r in vr.results
                    ],
                }
                for vr in self.validator_reports
            ],
            "build_stats": self.build_stats,
        }
