"""Output formatters for MCP Security Audit results.

Provides text (terminal) and JSON output formats.
"""

from __future__ import annotations

import json
from typing import Any

from .models import Finding, ScanResult, ScanSummary, Severity


def format_text(
    results: list[ScanResult],
    show_remediation: bool = False,
) -> str:
    """Format scan results as human-readable terminal output.

    Args:
        results: List of scan results to format.
        show_remediation: If True, include remediation guidance per finding.

    Returns:
        Formatted string with findings, scores, and summary.
    """
    output: list[str] = []
    total_findings = sum(len(r.findings) for r in results)
    total_lines = sum(r.lines_scanned for r in results)

    output.append(f"\n{'=' * 60}")
    output.append("  MCP Security Audit — Results")
    output.append(f"{'=' * 60}")
    output.append(f"  Files scanned: {len(results)}")
    output.append(f"  Lines scanned: {total_lines:,}")
    output.append(f"  Total findings: {total_findings}")
    output.append(f"{'=' * 60}\n")

    for result in results:
        if not result.findings:
            output.append(
                f"  [OK] {result.file} — Grade: {result.grade} (0 findings)"
            )
            continue

        output.append(f"\n  [FILE] {result.file}")
        output.append(
            f"     Grade: {result.grade} | "
            f"{len(result.findings)} findings | "
            f"{result.scan_time_ms:.1f}ms\n"
        )

        severity_order = list(Severity)
        sorted_findings = sorted(
            result.findings,
            key=lambda x: severity_order.index(x.severity),
        )
        for f in sorted_findings:
            icon = _severity_icon(f.severity)
            confidence_tag = f" [{f.confidence}]" if f.confidence else ""
            output.append(f"     {icon} [{f.rule_id}] {f.title}{confidence_tag}")
            output.append(f"       Line {f.line}: {f.description}")
            if f.code_snippet:
                output.append(f"       Code: {f.code_snippet}")
            if f.recommendation:
                output.append(f"       Fix: {f.recommendation}")
            if show_remediation and f.remediation:
                output.append(f"       Remediation: {f.remediation}")
            output.append("")

    output.append(f"{'=' * 60}")
    return "\n".join(output)


def format_json(results: list[ScanResult]) -> str:
    """Format scan results as JSON for CI/CD integration.

    Args:
        results: List of scan results to format.

    Returns:
        JSON string with findings and summary.
    """
    summary = ScanSummary(results=results)
    return json.dumps(summary.to_dict(), indent=2, ensure_ascii=False)


def format_summary_text(
    summary: ScanSummary,
    show_remediation: bool = False,
) -> str:
    """Format a ScanSummary as human-readable text.

    Args:
        summary: Aggregate scan summary.
        show_remediation: If True, include remediation guidance per finding.

    Returns:
        Formatted summary string.
    """
    return format_text(summary.results, show_remediation=show_remediation)


def format_summary_json(summary: ScanSummary) -> str:
    """Format a ScanSummary as JSON.

    Args:
        summary: Aggregate scan summary.

    Returns:
        JSON string with full summary.
    """
    return json.dumps(summary.to_dict(), indent=2, ensure_ascii=False)


def _severity_icon(severity: Severity) -> str:
    """Get a plain-text icon for a severity level.

    Args:
        severity: The severity level.

    Returns:
        Icon string for terminal output.
    """
    icons: dict[Severity, str] = {
        Severity.CRITICAL: "[!!]",
        Severity.HIGH: "[!]",
        Severity.MEDIUM: "[-]",
        Severity.LOW: "[.]",
        Severity.INFO: "[i]",
    }
    return icons.get(severity, "[?]")
