"""
Report generation: JSON, Markdown, and dependency list.
Now includes risk scores in output.
"""

from __future__ import annotations

import json
import logging
from datetime import datetime
from pathlib import Path
from typing import List

from ..scanner.dependency_parser import Dependency
from ..scanner.confusion_checker import VulnerableDependency
from ..utils.risk_engine import RiskResult

logger = logging.getLogger(__name__)

_VERSION = "2.0.0"


class ReportWriter:
    """Write scan results to disk in multiple formats."""

    def __init__(self, output_dir: Path):
        self.output_dir = output_dir

    def generate_all(
        self,
        target: str,
        dependencies: List[Dependency],
        vulnerabilities: List[VulnerableDependency],
        poc_paths: List[Path],
        risk_results: List[RiskResult] | None = None,
        secrets: List[str] | None = None,
    ) -> None:
        """Write all report formats."""
        self._write_dependencies_json(dependencies)
        self._write_report_json(target, dependencies, vulnerabilities, poc_paths, risk_results, secrets)
        self._write_report_markdown(target, dependencies, vulnerabilities, poc_paths, risk_results, secrets)
        logger.info(f"Reports written to {self.output_dir}")

    # ── JSON ──────────────────────────────────────────────────────────────────

    def _write_dependencies_json(self, dependencies: List[Dependency]) -> None:
        out = self.output_dir / "dependencies.json"
        out.write_text(json.dumps([d.to_dict() for d in dependencies], indent=2), encoding="utf-8")
        logger.info(f"Wrote {out}")

    def _write_report_json(
        self,
        target: str,
        dependencies: List[Dependency],
        vulnerabilities: List[VulnerableDependency],
        poc_paths: List[Path],
        risk_results: List[RiskResult] | None,
        secrets: List[str] | None,
    ) -> None:
        ecosystems: dict = {}
        for dep in dependencies:
            ecosystems[dep.ecosystem] = ecosystems.get(dep.ecosystem, 0) + 1

        report = {
            "scan_date": datetime.now().isoformat(),
            "target": target,
            "scanner_version": _VERSION,
            "summary": {
                "total_dependencies": len(dependencies),
                "vulnerable_dependencies": len(vulnerabilities),
                "generated_pocs": len(poc_paths),
                "ecosystems": ecosystems,
            },
            "vulnerabilities": [v.to_dict() for v in vulnerabilities],
            "risk_scores": [r.to_dict() for r in (risk_results or [])],
            "poc_packages": [str(p) for p in poc_paths],
            "secrets_found": secrets or [],
        }

        out = self.output_dir / "report.json"
        out.write_text(json.dumps(report, indent=2), encoding="utf-8")
        logger.info(f"Wrote {out}")

    # ── Markdown ──────────────────────────────────────────────────────────────

    def _write_report_markdown(
        self,
        target: str,
        dependencies: List[Dependency],
        vulnerabilities: List[VulnerableDependency],
        poc_paths: List[Path],
        risk_results: List[RiskResult] | None,
        secrets: List[str] | None,
    ) -> None:
        ecosystems: dict = {}
        for dep in dependencies:
            ecosystems[dep.ecosystem] = ecosystems.get(dep.ecosystem, 0) + 1

        md = f"""# DepRaptor Scan Report

## Scan Information

| Field | Value |
|-------|-------|
| Date | {datetime.now().strftime("%Y-%m-%d %H:%M:%S")} |
| Target | `{target}` |
| Scanner | DepRaptor v{_VERSION} |
| Developer | LAKSHMIKANTHAN K (letchupkt) |

## Summary

| Metric | Count |
|--------|-------|
| Total Dependencies | {len(dependencies)} |
| Vulnerable Dependencies | {len(vulnerabilities)} |
| Generated PoC Packages | {len(poc_paths)} |

## Ecosystem Breakdown

"""
        for eco, count in ecosystems.items():
            md += f"- **{eco}**: {count} packages\n"

        # Vulnerabilities
        if vulnerabilities:
            md += "\n## Vulnerabilities Detected\n\n"
            for vuln in vulnerabilities:
                md += f"### `{vuln.dependency.name}`\n\n"
                md += f"- **Ecosystem**: {vuln.dependency.ecosystem}\n"
                md += f"- **Version**: {vuln.dependency.version}\n"
                md += f"- **Source**: `{vuln.dependency.source}`\n"
                md += f"- **Reason**: {vuln.reason}\n\n"
        else:
            md += "\n## No Vulnerabilities Detected\n\nAll dependencies found in public registries.\n"

        # Risk scores
        if risk_results:
            md += "\n## Risk Scores\n\n"
            md += "| Package | Ecosystem | Score | Reasons |\n"
            md += "|---------|-----------|-------|---------|\n"
            for r in risk_results:
                reasons = "; ".join(r.reasons)
                md += f"| `{r.package}` | {r.ecosystem} | **{r.score}** | {reasons} |\n"

        # PoC packages
        if poc_paths:
            md += "\n## Generated PoC Packages\n\n"
            for p in poc_paths:
                md += f"- `{p}`\n"

        # Secrets
        if secrets:
            md += "\n## Secrets Found\n\n"
            for s in secrets:
                md += f"- {s}\n"

        md += "\n---\n\n> **WARNING**: PoC packages are for authorized testing only.\n"

        out = self.output_dir / "report.md"
        out.write_text(md, encoding="utf-8")
        logger.info(f"Wrote {out}")
