"""Markdown report generator for ActionsGuard."""

import logging
from pathlib import Path
from datetime import datetime

from actionsguard.reporters.base import BaseReporter
from actionsguard.models import ScanSummary, ScanResult, Severity, Status, RiskLevel


logger = logging.getLogger("actionsguard")


class MarkdownReporter(BaseReporter):
    """Generate Markdown reports."""

    EMOJI_MAP = {
        RiskLevel.CRITICAL: "🔴",
        RiskLevel.HIGH: "🟠",
        RiskLevel.MEDIUM: "🟡",
        RiskLevel.LOW: "🟢",
    }

    STATUS_EMOJI = {
        Status.PASS: "✅",
        Status.WARN: "⚠️",
        Status.FAIL: "❌",
        Status.ERROR: "💥",
        Status.SKIP: "⏭️",
    }

    def generate_report(self, summary: ScanSummary, filename: str = "report") -> Path:
        """
        Generate Markdown report.

        Args:
            summary: Scan summary
            filename: Output filename (without extension)

        Returns:
            Path to generated Markdown file
        """
        output_path = self.output_dir / f"{filename}.md"

        # Get executive summary
        exec_summary = summary.get_executive_summary()

        with open(output_path, "w", encoding="utf-8") as f:
            # Title
            f.write("# 🛡️ ActionsGuard Security Report\n\n")
            f.write(f"**Generated:** {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n")

            # Executive Summary
            f.write("## 📊 Executive Summary\n\n")

            # Metrics Grid
            f.write("| Metric | Value |\n")
            f.write("|--------|-------|\n")
            f.write(
                f"| Total Repositories | {exec_summary['total_repositories']} ({summary.successful_scans} scanned successfully) |\n"
            )
            f.write(f"| Average Score | {exec_summary['average_score']:.1f}/10 |\n")
            f.write(f"| Total Issues | {exec_summary['issue_counts']['total']} |\n")
            if summary.scan_duration:
                f.write(f"| Scan Duration | {summary.scan_duration:.1f}s |\n")
            f.write("\n")

            # Risk Distribution
            f.write("### Risk Distribution\n\n")
            risk_dist = exec_summary["risk_distribution"]
            f.write(f"- 🔴 **Critical:** {risk_dist['CRITICAL']} repositories\n")
            f.write(f"- 🟠 **High:** {risk_dist['HIGH']} repositories\n")
            f.write(f"- 🟡 **Medium:** {risk_dist['MEDIUM']} repositories\n")
            f.write(f"- 🟢 **Low:** {risk_dist['LOW']} repositories\n")
            f.write("\n")

            # Top Issues
            if exec_summary.get("top_issues"):
                f.write("### 🔍 Top Security Issues\n\n")
                f.write("| Issue | Instances | Repos Affected |\n")
                f.write("|-------|-----------|----------------|\n")
                for issue in exec_summary["top_issues"][:5]:
                    f.write(
                        f"| {issue['name']} | {issue['instances']} | {issue['repos_affected']} |\n"
                    )
                f.write("\n")

            # Repository Details
            f.write("## 📁 Repository Details\n\n")

            # Results by risk level (sorted highest to lowest)
            critical_repos = [
                r for r in summary.results if r.risk_level == RiskLevel.CRITICAL and not r.error
            ]
            high_repos = [
                r for r in summary.results if r.risk_level == RiskLevel.HIGH and not r.error
            ]
            medium_repos = [
                r for r in summary.results if r.risk_level == RiskLevel.MEDIUM and not r.error
            ]
            low_repos = [
                r for r in summary.results if r.risk_level == RiskLevel.LOW and not r.error
            ]
            error_repos = [r for r in summary.results if r.error]

            # Critical Risk Repos (highest priority first)
            if critical_repos:
                f.write("### 🔴 Critical Risk Repositories\n\n")
                for result in critical_repos:
                    self._write_repository_section(f, result)

            # High Risk Repos
            if high_repos:
                f.write("### 🟠 High Risk Repositories\n\n")
                for result in high_repos:
                    self._write_repository_section(f, result)

            # Medium Risk Repos
            if medium_repos:
                f.write("### 🟡 Medium Risk Repositories\n\n")
                for result in medium_repos:
                    self._write_repository_section(f, result)

            # Low Risk Repos
            if low_repos:
                f.write("### 🟢 Low Risk Repositories\n\n")
                for result in low_repos:
                    self._write_repository_section(f, result, collapsed=True)

            # Failed Scans
            if error_repos:
                f.write("## 💥 Failed Scans\n\n")
                for result in error_repos:
                    f.write(f"### [{result.repo_name}]({result.repo_url})\n\n")
                    f.write(f"**Error:** {result.error}\n\n")

            # Footer
            f.write("---\n\n")
            f.write(
                "*Generated by [ActionsGuard](https://github.com/your-username/actionsguard)*\n"
            )

        logger.info(f"Generated Markdown report: {output_path}")
        return output_path

    def _write_repository_section(self, f, result: ScanResult, collapsed: bool = False) -> None:
        """Write a repository section to the markdown file."""
        emoji = self.EMOJI_MAP.get(result.risk_level, "⚪")

        f.write(f"### {emoji} [{result.repo_name}]({result.repo_url})\n\n")
        f.write(f"**Score:** {result.score:.1f}/10.0 | **Risk:** {result.risk_level.value}\n\n")

        if not result.metadata.get("has_workflows", True):
            f.write("*No GitHub Actions workflows detected*\n\n")
            return

        # Workflow-level findings
        if result.workflows:
            f.write("#### 📁 Workflow Security Analysis\n\n")
            for workflow in result.workflows:
                f.write(
                    f"##### `{workflow.path}` ({len(workflow.findings)} issue{'s' if len(workflow.findings) != 1 else ''})\n\n"
                )

                for finding in workflow.findings:
                    severity_emoji = self._get_severity_emoji(finding.severity)
                    f.write(
                        f"**{severity_emoji} {finding.check_name}** ({finding.severity.value})\n\n"
                    )
                    f.write(f"{finding.message}\n\n")

                    if finding.line_number:
                        f.write(f"📍 **Line:** {finding.line_number}\n\n")

                    if finding.recommendation:
                        f.write(f"> 💡 **How to Fix:** {finding.recommendation}\n\n")

                    f.write("---\n\n")
        else:
            # Fallback to check-based view if no workflow-level findings
            failed_checks = [c for c in result.checks if c.status == Status.FAIL]
            warn_checks = [c for c in result.checks if c.status == Status.WARN]

            if failed_checks or warn_checks:
                # Failed checks
                if failed_checks:
                    f.write("#### ❌ Security Issues Detected\n\n")
                    for check in failed_checks:
                        severity_emoji = self._get_severity_emoji(check.severity)
                        f.write(f"**{severity_emoji} {check.name}** ({check.severity.value})\n\n")
                        f.write(f"Score: {check.score}/10 - {check.reason}\n\n")
                        if check.documentation_url:
                            f.write(
                                f"> 📚 **Documentation:** [{check.documentation_url}]({check.documentation_url})\n\n"
                            )
                        f.write("---\n\n")

                # Warning checks
                if warn_checks and not collapsed:
                    f.write("#### ⚠️ Warnings\n\n")
                    for check in warn_checks:
                        severity_emoji = self._get_severity_emoji(check.severity)
                        f.write(f"**{severity_emoji} {check.name}** ({check.severity.value})\n\n")
                        f.write(f"Score: {check.score}/10 - {check.reason}\n\n")
                        if check.documentation_url:
                            f.write(
                                f"> 📚 **Documentation:** [{check.documentation_url}]({check.documentation_url})\n\n"
                            )
                        f.write("---\n\n")

                # Passed checks (collapsed)
                pass_checks = [c for c in result.checks if c.status == Status.PASS]
                if pass_checks and not collapsed:
                    f.write("<details>\n<summary>✅ Passed Checks</summary>\n\n")
                    for check in pass_checks:
                        f.write(f"- {check.name} (Score: {check.score}/10)\n")
                    f.write("\n</details>\n\n")
            else:
                # All checks passed
                f.write("✅ All security checks passed.\n\n")

        f.write("---\n\n")

    def _get_severity_emoji(self, severity: Severity) -> str:
        """Get emoji for severity level."""
        mapping = {
            Severity.CRITICAL: "🔴",
            Severity.HIGH: "🟠",
            Severity.MEDIUM: "🟡",
            Severity.LOW: "🟢",
            Severity.INFO: "ℹ️",
        }
        return mapping.get(severity, "⚪")

    def get_extension(self) -> str:
        """Get file extension."""
        return ".md"
