"""
Basilisk HTML Report Generator — Jinja2-based vulnerability reports.

Generates professional dark-themed HTML reports with:
  - Executive summary with severity breakdown
  - Finding details with expandable payloads and responses
  - Conversation replay sections
  - OWASP LLM Top 10 mapping
  - Evolution data (if available)
"""

from __future__ import annotations

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

from basilisk.core.session import ScanSession


def generate_html(session: ScanSession, path: Path) -> None:
    """Generate a styled HTML report from scan findings."""
    summary = session.summary
    findings_html = _render_findings(session)
    profile_html = _render_profile(session)
    severity_chart = _render_severity_chart(summary)

    html = f"""<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Basilisk Scan Report — {session.id}</title>
    <style>
{_get_styles()}
    </style>
</head>
<body>
    <div class="container">
        <header class="header">
            <h1>🐍 Basilisk Scan Report</h1>
            <p class="subtitle">
                Session: <code>{session.id}</code> |
                Target: <code>{_esc(session.config.target.url)}</code> |
                {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}
            </p>
        </header>

        {severity_chart}

        <section class="meta-grid">
            <div class="meta-card">
                <div class="meta-label">Mode</div>
                <div class="meta-value">{session.config.mode.value.upper()}</div>
            </div>
            <div class="meta-card">
                <div class="meta-label">Model</div>
                <div class="meta-value">{_esc(session.profile.detected_model)}</div>
            </div>
            <div class="meta-card">
                <div class="meta-label">Provider</div>
                <div class="meta-value">{_esc(session.profile.provider.value)}</div>
            </div>
            <div class="meta-card">
                <div class="meta-label">Attack Surface</div>
                <div class="meta-value">{session.profile.attack_surface_score:.1f}/10</div>
            </div>
        </section>

        {profile_html}

        <h2>Findings ({len(session.findings)})</h2>
        {findings_html if session.findings else '<p class="empty">No vulnerabilities detected.</p>'}

        <footer>
            <p>Generated by <strong>Basilisk</strong> v0.1.0 — AI Red Teaming Framework</p>
            <p>Built by <a href="https://rothackers.com">Rot Hackers</a></p>
        </footer>
    </div>
</body>
</html>"""

    with open(path, "w") as f:
        f.write(html)


def _render_severity_chart(summary: dict[str, Any]) -> str:
    """Render severity breakdown cards."""
    severities = [
        ("CRITICAL", summary["severity_counts"].get("critical", 0), "#dc2626"),
        ("HIGH", summary["severity_counts"].get("high", 0), "#ea580c"),
        ("MEDIUM", summary["severity_counts"].get("medium", 0), "#ca8a04"),
        ("LOW", summary["severity_counts"].get("low", 0), "#2563eb"),
        ("INFO", summary["severity_counts"].get("info", 0), "#6b7280"),
    ]

    cards = ""
    for name, count, color in severities:
        cards += f"""
        <div class="stat">
            <div class="stat-value" style="color: {color};">{count}</div>
            <div class="stat-label">{name}</div>
        </div>"""

    return f'<div class="stats">{cards}</div>'


def _render_findings(session: ScanSession) -> str:
    """Render all findings as HTML cards."""
    html = ""
    for f in sorted(session.findings, key=lambda x: x.severity.numeric, reverse=True):
        color = {
            "critical": "#dc2626", "high": "#ea580c",
            "medium": "#ca8a04", "low": "#2563eb", "info": "#6b7280"
        }.get(f.severity.value, "#6b7280")

        conv_html = ""
        if f.conversation:
            conv_html = '<div class="conversation"><h4>Conversation Replay</h4>'
            for msg in f.conversation:
                role_class = "msg-user" if msg.role == "user" else "msg-assistant"
                conv_html += f'<div class="msg {role_class}"><span class="role">{msg.role}</span><span class="content">{_esc(msg.content[:500])}</span></div>'
            conv_html += '</div>'

        evo_badge = f'<span class="evo-badge">Gen {f.evolution_generation}</span>' if f.evolution_generation else ''

        html += f"""
        <div class="finding" style="border-left: 4px solid {color};">
            <div class="finding-hdr">
                <span class="sev-badge" style="background: {color};">{f.severity.value.upper()}</span>
                <span class="finding-id">{f.id}</span>
                <span class="owasp">{f.category.owasp_id}</span>
                {evo_badge}
            </div>
            <h3>{_esc(f.title)}</h3>
            <p class="desc">{_esc(f.description)}</p>
            <div class="meta-row">
                <span>Module: <code>{_esc(f.attack_module)}</code></span>
                <span>Confidence: <strong>{f.confidence:.0%}</strong></span>
            </div>
            <details>
                <summary>Payload</summary>
                <pre><code>{_esc(f.payload)}</code></pre>
            </details>
            <details>
                <summary>Response</summary>
                <pre><code>{_esc(f.response[:1000])}</code></pre>
            </details>
            {conv_html}
            <p class="remediation"><strong>Remediation:</strong> {_esc(f.remediation)}</p>
        </div>"""

    return html


def _render_profile(session: ScanSession) -> str:
    """Render recon profile section."""
    p = session.profile
    tools_html = ""
    if p.detected_tools:
        tools_html = "<h4>Detected Tools</h4><ul>"
        for t in p.detected_tools:
            tools_html += f'<li><strong>{_esc(t.name)}</strong> — {_esc(t.description)} (risk: {t.risk_level})</li>'
        tools_html += "</ul>"

    return f"""
    <section class="profile-section">
        <h2>Target Profile</h2>
        <div class="meta-grid">
            <div class="meta-card"><div class="meta-label">Context Window</div><div class="meta-value">{p.context_window:,} tokens</div></div>
            <div class="meta-card"><div class="meta-label">Guardrails</div><div class="meta-value">{p.guardrails.level.value}</div></div>
            <div class="meta-card"><div class="meta-label">RAG</div><div class="meta-value">{'Detected' if p.rag_detected else 'No'}</div></div>
            <div class="meta-card"><div class="meta-label">Tools</div><div class="meta-value">{len(p.detected_tools)}</div></div>
        </div>
        {tools_html}
    </section>"""


def _get_styles() -> str:
    """Return CSS styles for the report."""
    return """
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: 'Segoe UI', system-ui, -apple-system, sans-serif; background: #0a0a0a; color: #e5e5e5; }
        .container { max-width: 1100px; margin: 0 auto; padding: 2rem; }
        .header { text-align: center; padding: 2.5rem 0; border-bottom: 2px solid #dc2626; margin-bottom: 2rem; }
        .header h1 { font-size: 2.5rem; color: #dc2626; letter-spacing: -0.02em; }
        .header .subtitle { color: #a3a3a3; margin-top: 0.5rem; font-size: 0.9rem; }
        code { background: #1a1a1a; padding: 2px 6px; border-radius: 3px; font-size: 0.85em; }
        .stats { display: grid; grid-template-columns: repeat(5, 1fr); gap: 1rem; margin: 1.5rem 0; }
        .stat { background: #171717; border-radius: 8px; padding: 1.2rem; text-align: center; border: 1px solid #262626; }
        .stat-value { font-size: 2.2rem; font-weight: 700; }
        .stat-label { color: #a3a3a3; font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.05em; margin-top: 0.3rem; }
        .meta-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; margin: 1.5rem 0; }
        .meta-card { background: #171717; border-radius: 8px; padding: 1rem; border: 1px solid #262626; }
        .meta-label { font-size: 0.75rem; color: #a3a3a3; text-transform: uppercase; letter-spacing: 0.05em; }
        .meta-value { font-size: 1.1rem; font-weight: 600; margin-top: 0.3rem; }
        h2 { margin: 2rem 0 1rem; font-size: 1.5rem; }
        .finding { background: #171717; border-radius: 8px; padding: 1.5rem; margin: 1rem 0; border: 1px solid #262626; }
        .finding-hdr { display: flex; gap: 0.5rem; align-items: center; margin-bottom: 0.5rem; flex-wrap: wrap; }
        .sev-badge { color: white; padding: 3px 10px; border-radius: 4px; font-size: 0.7rem; font-weight: 700; text-transform: uppercase; }
        .finding-id { color: #737373; font-size: 0.8rem; font-family: monospace; }
        .owasp { color: #22d3ee; font-size: 0.8rem; font-weight: 600; }
        .evo-badge { color: #a78bfa; font-size: 0.75rem; background: #1e1b4b; padding: 2px 8px; border-radius: 3px; }
        h3 { margin: 0.5rem 0; font-size: 1.1rem; }
        .desc { color: #a3a3a3; font-size: 0.9rem; margin: 0.3rem 0; }
        .meta-row { display: flex; gap: 1.5rem; margin: 0.5rem 0; font-size: 0.85rem; color: #a3a3a3; }
        details { margin: 0.5rem 0; }
        summary { cursor: pointer; color: #60a5fa; font-size: 0.9rem; padding: 0.3rem 0; }
        pre { background: #0a0a0a; padding: 1rem; border-radius: 6px; overflow-x: auto; margin: 0.5rem 0; font-size: 0.82rem; border: 1px solid #262626; }
        .remediation { color: #4ade80; margin-top: 0.8rem; font-size: 0.9rem; }
        .conversation { margin-top: 1rem; border-top: 1px solid #262626; padding-top: 0.8rem; }
        .conversation h4 { font-size: 0.85rem; color: #a3a3a3; margin-bottom: 0.5rem; }
        .msg { padding: 0.5rem; margin: 0.3rem 0; border-radius: 4px; font-size: 0.85rem; }
        .msg-user { background: #1e293b; }
        .msg-assistant { background: #1a2e1a; }
        .role { font-weight: 600; margin-right: 0.5rem; }
        .msg-user .role { color: #60a5fa; }
        .msg-assistant .role { color: #4ade80; }
        .content { color: #d4d4d4; }
        .profile-section { margin: 2rem 0; }
        .profile-section ul { margin: 0.5rem 0 0 1.5rem; }
        .profile-section li { margin: 0.3rem 0; color: #d4d4d4; font-size: 0.9rem; }
        .empty { color: #737373; text-align: center; padding: 3rem 0; }
        footer { text-align: center; margin-top: 3rem; padding: 2rem 0; border-top: 1px solid #262626; color: #737373; font-size: 0.85rem; }
        footer a { color: #dc2626; text-decoration: none; }
        @media (max-width: 768px) {
            .stats { grid-template-columns: repeat(3, 1fr); }
            .meta-grid { grid-template-columns: repeat(2, 1fr); }
        }
    """


def _esc(text: str) -> str:
    """HTML escape."""
    if not text:
        return ""
    return text.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;").replace('"', "&quot;")
