"""Markdown report formatter for scan results."""

from collections import Counter
from datetime import datetime, timezone


def _sev_name(severity) -> str:
    return (severity.name if hasattr(severity, "name") else str(severity)).upper()


def _cls_name(classification) -> str:
    return (classification.name if hasattr(classification, "name") else str(classification)).upper()


class MarkdownFormatter:
    """Generates a Markdown security scan report."""

    def format(self, result, duration_ms: int) -> str:
        lines: list[str] = []
        now = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S UTC")

        lines.append("# ApiPosture Pro Security Scan Report")
        lines.append("")
        lines.append(f"**Generated:** {now}")
        lines.append("")

        # Summary table
        lines.append("## Summary")
        lines.append("")
        lines.append("| Metric | Value |")
        lines.append("|--------|-------|")
        lines.append(f"| Scanned Path | `{result.scan_path}` |")
        lines.append(f"| Files Scanned | {len(getattr(result, 'files_scanned', []))} |")
        lines.append(f"| Failed Files | {len(getattr(result, 'parse_errors', {}))} |")
        lines.append(f"| Total Endpoints | {len(result.endpoints)} |")
        lines.append(f"| Total Findings | {len(result.findings)} |")
        lines.append(f"| Scan Duration | {duration_ms:,}ms |")
        lines.append("")

        # Severity breakdown
        if result.findings:
            severity_counts = Counter(_sev_name(f.severity) for f in result.findings)
            lines.append("### Findings by Severity")
            lines.append("")
            for sev in ["CRITICAL", "HIGH", "MEDIUM", "LOW", "INFO"]:
                count = severity_counts.get(sev, 0)
                if count > 0:
                    lines.append(f"- **{sev}:** {count}")
            lines.append("")

        # Endpoints table
        lines.append("## Discovered Endpoints")
        lines.append("")
        if result.endpoints:
            lines.append("| Route | Methods | Type | Classification |")
            lines.append("|-------|---------|------|----------------|")
            for ep in result.endpoints:
                route = str(getattr(ep, "full_route", ep.route))
                methods_str = ", ".join(
                    m.value if hasattr(m, "value") else str(m) for m in ep.methods
                )
                ep_type = ep.endpoint_type
                type_str = (ep_type.value if hasattr(ep_type, "value") else str(ep_type)).lower()
                cls = _cls_name(ep.classification)
                lines.append(f"| `{route}` | {methods_str} | {type_str} | {cls} |")
        else:
            lines.append("*No endpoints discovered.*")
        lines.append("")

        # Findings detail
        lines.append("## Security Findings")
        lines.append("")
        if not result.findings:
            lines.append("✓ No security findings detected!")
        else:
            sorted_findings = sorted(
                result.findings,
                key=lambda f: {"CRITICAL": 0, "HIGH": 1, "MEDIUM": 2, "LOW": 3, "INFO": 4}.get(
                    _sev_name(f.severity), 5
                ),
            )
            for f in sorted_findings:
                sev = _sev_name(f.severity)
                ep = getattr(f, "endpoint", None)
                route = str(getattr(ep, "full_route", getattr(ep, "route", ""))) if ep else ""
                file_path = str(ep.file_path) if ep else ""
                line_number = ep.line_number if ep else 0

                lines.append(f"### [{f.rule_id}] {f.rule_name}")
                lines.append("")
                lines.append(f"**Severity:** {sev}")
                if route:
                    lines.append(f"**Route:** `{route}`")
                if file_path:
                    lines.append(f"**Location:** `{file_path}:{line_number}`")
                lines.append("")
                lines.append(f.message)
                if f.recommendation:
                    lines.append("")
                    lines.append(f"> **Recommendation:** {f.recommendation}")
                lines.append("")
                lines.append("---")
                lines.append("")

        return "\n".join(lines)
