"""
Basilisk Report Generator — multi-format vulnerability reporting.

Orchestrates report generation across HTML, JSON, SARIF, Markdown,
and PDF formats. Each format has its own module for detailed rendering.
"""

from __future__ import annotations

import json
from datetime import datetime, timezone
from pathlib import Path
from typing import Any

from basilisk.core.config import OutputConfig
from basilisk.core.session import ScanSession


async def generate_report(session: ScanSession, output_config: OutputConfig) -> str:
    """Generate a report in the configured format."""
    output_dir = Path(output_config.output_dir)
    output_dir.mkdir(parents=True, exist_ok=True)

    timestamp = datetime.now(timezone.utc).strftime("%Y%m%d_%H%M%S")
    base_name = f"basilisk_{session.id}_{timestamp}"

    fmt = output_config.format.lower()
    if fmt == "json":
        path = output_dir / f"{base_name}.json"
        _write_json_report(session, path)
    elif fmt == "sarif":
        path = output_dir / f"{base_name}.sarif"
        from basilisk.report.sarif import generate_sarif
        generate_sarif(session, path)
    elif fmt == "markdown":
        path = output_dir / f"{base_name}.md"
        _write_markdown_report(session, path)
    elif fmt == "pdf":
        path = output_dir / f"{base_name}.pdf"
        from basilisk.report.pdf import generate_pdf
        generate_pdf(session, path)
    elif fmt == "html":
        path = output_dir / f"{base_name}.html"
        from basilisk.report.html import generate_html
        generate_html(session, path)
    else:
        path = output_dir / f"{base_name}.json"
        _write_json_report(session, path)

    return str(path)


def _write_json_report(session: ScanSession, path: Path) -> None:
    """Write a JSON report."""
    report = {
        "basilisk_version": "0.1.0",
        "generated_at": datetime.now(timezone.utc).isoformat(),
        "session": session.summary,
        "profile": session.profile.to_dict(),
        "findings": [f.to_dict() for f in session.findings],
    }
    with open(path, "w") as f:
        json.dump(report, f, indent=2, default=str)


def _write_markdown_report(session: ScanSession, path: Path) -> None:
    """Write a Markdown report."""
    lines = [
        "# 🐍 Basilisk Scan Report",
        "",
        f"**Session:** `{session.id}`",
        f"**Target:** `{session.config.target.url}`",
        f"**Date:** {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}",
        f"**Mode:** {session.config.mode.value}",
        f"**Model:** {session.profile.detected_model}",
        f"**Total Findings:** {len(session.findings)}",
        "",
        "## Summary",
        "",
        "| Severity | Count |",
        "|----------|-------|",
    ]

    summary = session.summary
    for sev in ["critical", "high", "medium", "low", "info"]:
        count = summary["severity_counts"].get(sev, 0)
        lines.append(f"| {sev.upper()} | {count} |")

    lines.extend(["", "## Target Profile", ""])
    for line in session.profile.summary_lines():
        lines.append(f"- {line}")

    lines.extend(["", "## Findings", ""])

    for f in sorted(session.findings, key=lambda x: x.severity.numeric, reverse=True):
        lines.extend([
            f"### {f.severity.icon} [{f.severity.value.upper()}] {f.title}",
            "",
            f"**ID:** `{f.id}`",
            f"**Category:** {f.category.value} ({f.category.owasp_id})",
            f"**Module:** `{f.attack_module}`",
            f"**Confidence:** {f.confidence:.0%}",
            "",
            f"**Payload:**",
            f"```",
            f"{f.payload}",
            f"```",
            "",
            f"**Response:**",
            f"```",
            f"{f.response[:500]}",
            f"```",
            "",
            f"**Remediation:** {f.remediation}",
            "",
        ])
        if f.conversation:
            lines.extend(["**Conversation:**", ""])
            for msg in f.conversation:
                lines.append(f"> **{msg.role}:** {msg.content[:300]}")
            lines.append("")

        lines.extend(["---", ""])

    lines.extend([
        "",
        "---",
        "*Generated by Basilisk v0.1.0 — AI Red Teaming Framework | [Rot Hackers](https://rothackers.com)*",
    ])

    with open(path, "w") as f:
        f.write("\n".join(lines))
