"""
AIPT HTML Report Template

Generates a standalone HTML report with embedded CSS.

Supports two formats:
- Legacy: generate_html_report(data) - single list of findings
- V2: generate_html_report_v2(data, canonical) - separate sections for
      Confirmed/Needs Review/Suppressed findings
"""

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from .generator import ReportData
    from ..pipeline.persistence import CanonicalFindings


def generate_html_report(data: "ReportData") -> str:
    """Generate standalone HTML report"""

    severity_counts = data.get_severity_counts()
    risk_score = data.get_risk_score()
    risk_rating = data.get_risk_rating()

    # Build findings HTML
    findings_html = ""

    for severity_name, findings, color in [
        ("Critical", data.critical_findings, "#dc2626"),
        ("High", data.high_findings, "#ea580c"),
        ("Medium", data.medium_findings, "#ca8a04"),
        ("Low", data.low_findings, "#2563eb"),
        ("Informational", data.info_findings, "#6b7280"),
    ]:
        if findings:
            findings_html += f"""
            <div class="severity-section">
                <h2 style="color: {color};">{severity_name} Severity ({len(findings)})</h2>
            """

            for i, finding in enumerate(findings, 1):
                evidence_html = ""
                if finding.evidence and data.config.include_evidence:
                    evidence_html = f"""
                    <div class="evidence">
                        <strong>Evidence:</strong>
                        <pre>{_escape_html(finding.evidence[:2000])}</pre>
                    </div>
                    """

                remediation_html = ""
                if finding.remediation and data.config.include_remediation:
                    remediation_html = f"""
                    <div class="remediation">
                        <strong>Remediation:</strong>
                        <p>{_escape_html(finding.remediation)}</p>
                    </div>
                    """

                ai_html = ""
                if finding.ai_reasoning and data.config.include_ai_reasoning:
                    ai_html = f"""
                    <div class="ai-reasoning">
                        <strong>AI Analysis:</strong>
                        <p>{_escape_html(finding.ai_reasoning[:500])}</p>
                    </div>
                    """

                findings_html += f"""
                <div class="finding" style="border-left-color: {color};">
                    <h3>{i}. {_escape_html(finding.title)}</h3>
                    <div class="finding-meta">
                        <span class="badge" style="background-color: {color};">{severity_name}</span>
                        <span class="badge source">{finding.source}</span>
                        <span class="vuln-type">{finding.vuln_type.value}</span>
                    </div>
                    <div class="finding-details">
                        <p><strong>URL:</strong> <code>{_escape_html(finding.url)}</code></p>
                        {f'<p><strong>Parameter:</strong> <code>{_escape_html(finding.parameter)}</code></p>' if finding.parameter else ''}
                        {f'<p><strong>Description:</strong> {_escape_html(finding.description)}</p>' if finding.description else ''}
                        {evidence_html}
                        {remediation_html}
                        {ai_html}
                    </div>
                </div>
                """

            findings_html += "</div>"

    # Risk color
    risk_colors = {
        "Critical": "#dc2626",
        "High": "#ea580c",
        "Medium": "#ca8a04",
        "Low": "#2563eb",
        "Informational": "#6b7280",
    }
    risk_color = risk_colors.get(risk_rating, "#6b7280")

    html = f"""<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Security Assessment Report - {_escape_html(data.target)}</title>
    <style>
        :root {{
            --primary: #1e40af;
            --critical: #dc2626;
            --high: #ea580c;
            --medium: #ca8a04;
            --low: #2563eb;
            --info: #6b7280;
            --bg: #f8fafc;
            --card-bg: #ffffff;
            --text: #1e293b;
            --text-muted: #64748b;
            --border: #e2e8f0;
        }}

        * {{
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }}

        body {{
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
            background: var(--bg);
            color: var(--text);
            line-height: 1.6;
        }}

        .container {{
            max-width: 1200px;
            margin: 0 auto;
            padding: 2rem;
        }}

        header {{
            background: linear-gradient(135deg, var(--primary), #3b82f6);
            color: white;
            padding: 3rem 2rem;
            margin-bottom: 2rem;
            border-radius: 0 0 1rem 1rem;
        }}

        header h1 {{
            font-size: 2rem;
            margin-bottom: 0.5rem;
        }}

        header .meta {{
            opacity: 0.9;
            font-size: 0.95rem;
        }}

        .summary-grid {{
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 1rem;
            margin-bottom: 2rem;
        }}

        .summary-card {{
            background: var(--card-bg);
            border-radius: 0.75rem;
            padding: 1.5rem;
            box-shadow: 0 1px 3px rgba(0,0,0,0.1);
        }}

        .summary-card h3 {{
            font-size: 0.875rem;
            color: var(--text-muted);
            text-transform: uppercase;
            letter-spacing: 0.05em;
            margin-bottom: 0.5rem;
        }}

        .summary-card .value {{
            font-size: 2rem;
            font-weight: 700;
        }}

        .risk-score {{
            background: {risk_color};
            color: white;
        }}

        .severity-breakdown {{
            display: flex;
            gap: 0.5rem;
            margin-top: 1rem;
        }}

        .severity-dot {{
            display: flex;
            align-items: center;
            gap: 0.25rem;
            font-size: 0.875rem;
        }}

        .severity-dot::before {{
            content: '';
            width: 12px;
            height: 12px;
            border-radius: 50%;
        }}

        .severity-dot.critical::before {{ background: var(--critical); }}
        .severity-dot.high::before {{ background: var(--high); }}
        .severity-dot.medium::before {{ background: var(--medium); }}
        .severity-dot.low::before {{ background: var(--low); }}
        .severity-dot.info::before {{ background: var(--info); }}

        .severity-section {{
            margin-bottom: 2rem;
        }}

        .severity-section h2 {{
            font-size: 1.5rem;
            margin-bottom: 1rem;
            padding-bottom: 0.5rem;
            border-bottom: 2px solid var(--border);
        }}

        .finding {{
            background: var(--card-bg);
            border-radius: 0.75rem;
            padding: 1.5rem;
            margin-bottom: 1rem;
            box-shadow: 0 1px 3px rgba(0,0,0,0.1);
            border-left: 4px solid;
        }}

        .finding h3 {{
            font-size: 1.125rem;
            margin-bottom: 0.75rem;
        }}

        .finding-meta {{
            display: flex;
            gap: 0.5rem;
            flex-wrap: wrap;
            margin-bottom: 1rem;
        }}

        .badge {{
            display: inline-block;
            padding: 0.25rem 0.75rem;
            border-radius: 9999px;
            font-size: 0.75rem;
            font-weight: 600;
            color: white;
        }}

        .badge.source {{
            background: var(--primary);
        }}

        .vuln-type {{
            font-size: 0.875rem;
            color: var(--text-muted);
        }}

        .finding-details p {{
            margin-bottom: 0.5rem;
        }}

        .finding-details code {{
            background: var(--bg);
            padding: 0.125rem 0.375rem;
            border-radius: 0.25rem;
            font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
            font-size: 0.875rem;
        }}

        .evidence, .remediation, .ai-reasoning {{
            margin-top: 1rem;
            padding: 1rem;
            background: var(--bg);
            border-radius: 0.5rem;
        }}

        .evidence pre {{
            white-space: pre-wrap;
            word-wrap: break-word;
            font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
            font-size: 0.8rem;
            max-height: 300px;
            overflow-y: auto;
        }}

        .ai-reasoning {{
            border-left: 3px solid var(--primary);
        }}

        footer {{
            text-align: center;
            padding: 2rem;
            color: var(--text-muted);
            font-size: 0.875rem;
        }}

        @media print {{
            body {{ background: white; }}
            .container {{ max-width: 100%; }}
            .finding {{ break-inside: avoid; }}
        }}
    </style>
</head>
<body>
    <header>
        <div class="container">
            <h1>Security Assessment Report</h1>
            <div class="meta">
                <p><strong>Target:</strong> {_escape_html(data.target)}</p>
                <p><strong>Scan ID:</strong> {data.scan_id}</p>
                <p><strong>Date:</strong> {data.generated_at.strftime('%B %d, %Y at %H:%M UTC')}</p>
                <p><strong>Client:</strong> {_escape_html(data.config.client_name)} | <strong>Project:</strong> {_escape_html(data.config.project_name)}</p>
            </div>
        </div>
    </header>

    <div class="container">
        <section class="summary-grid">
            <div class="summary-card risk-score">
                <h3>Risk Rating</h3>
                <div class="value">{risk_rating}</div>
                <div style="font-size: 0.875rem; opacity: 0.9;">Score: {risk_score}/100</div>
            </div>

            <div class="summary-card">
                <h3>Total Findings</h3>
                <div class="value">{data.total_findings}</div>
                <div class="severity-breakdown">
                    <span class="severity-dot critical">{severity_counts['critical']}</span>
                    <span class="severity-dot high">{severity_counts['high']}</span>
                    <span class="severity-dot medium">{severity_counts['medium']}</span>
                    <span class="severity-dot low">{severity_counts['low']}</span>
                </div>
            </div>

            <div class="summary-card">
                <h3>AI Findings</h3>
                <div class="value">{data.ai_findings_count}</div>
                <div style="font-size: 0.875rem; color: var(--text-muted);">Strix AI-discovered vulnerabilities</div>
            </div>

            <div class="summary-card">
                <h3>Scan Sources</h3>
                <div class="value">{len(data.sources)}</div>
                <div style="font-size: 0.875rem; color: var(--text-muted);">{', '.join(data.sources) if data.sources else 'N/A'}</div>
            </div>
        </section>

        <section class="findings">
            {findings_html if findings_html else '<p style="text-align: center; color: var(--text-muted); padding: 3rem;">No vulnerabilities found.</p>'}
        </section>
    </div>

    <footer>
        <p>Generated by <strong>AIPT</strong> - AI-Powered Penetration Testing Framework</p>
        <p>Report generated on {data.generated_at.strftime('%Y-%m-%d %H:%M:%S UTC')}</p>
    </footer>
</body>
</html>"""

    return html


def _escape_html(text: str) -> str:
    """Escape HTML special characters"""
    if not text:
        return ""
    return (
        str(text)
        .replace("&", "&amp;")
        .replace("<", "&lt;")
        .replace(">", "&gt;")
        .replace('"', "&quot;")
        .replace("'", "&#39;")
    )


def generate_html_report_v2(
    data: "ReportData",
    canonical: "CanonicalFindings",
) -> str:
    """
    Generate HTML report V2 with separate sections for Confirmed/Needs Review/Suppressed.

    This is the preferred format for the new pipeline.
    """
    from ..models.finding_v2 import SeverityV2, VerificationStatusV2

    severity_counts = data.get_severity_counts()
    risk_score = data.get_risk_score()
    risk_rating = data.get_risk_rating()

    # Get findings by verification status
    confirmed_findings = canonical.get_confirmed_findings()
    needs_review_findings = canonical.get_needs_review_findings()
    suppressed_findings = canonical.get_suppressed_findings()

    # Build confirmed findings HTML (main section)
    confirmed_html = _build_findings_section_v2(
        confirmed_findings,
        "Confirmed Vulnerabilities",
        "confirmed",
        include_evidence=data.config.include_evidence,
        include_remediation=data.config.include_remediation,
        include_ai_reasoning=data.config.include_ai_reasoning,
    )

    # Build needs review HTML (collapsible)
    needs_review_html = _build_findings_section_v2(
        needs_review_findings,
        "Needs Manual Review",
        "needs-review",
        include_evidence=data.config.include_evidence,
        include_remediation=data.config.include_remediation,
        include_ai_reasoning=data.config.include_ai_reasoning,
        collapsed=True,
    )

    # Build suppressed HTML (collapsible, collapsed by default)
    suppressed_html = _build_findings_section_v2(
        suppressed_findings,
        "Suppressed (False Positives)",
        "suppressed",
        include_evidence=False,
        include_remediation=False,
        include_ai_reasoning=False,
        collapsed=True,
    )

    # Risk color
    risk_colors = {
        "Critical": "#dc2626",
        "High": "#ea580c",
        "Medium": "#ca8a04",
        "Low": "#2563eb",
        "Informational": "#6b7280",
    }
    risk_color = risk_colors.get(risk_rating, "#6b7280")

    # Tool status HTML
    tool_status_html = ""
    for name, entry in canonical.tool_status.items():
        status_color = "#22c55e" if entry.status == "completed" else "#dc2626"
        status_icon = "✓" if entry.status == "completed" else "✗"
        error_html = f'<span class="tool-error">{_escape_html(entry.error or "")}</span>' if entry.error else ""
        tool_status_html += f'''
        <div class="tool-status-item">
            <span class="tool-name">{_escape_html(name)}</span>
            <span class="tool-status" style="color: {status_color};">{status_icon} {entry.status}</span>
            <span class="tool-count">{entry.finding_count} findings</span>
            {error_html}
        </div>
        '''

    html = f"""<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>VAPT Report - {_escape_html(data.target)}</title>
    <style>
        :root {{
            --primary: #1e40af;
            --critical: #dc2626;
            --high: #ea580c;
            --medium: #ca8a04;
            --low: #2563eb;
            --info: #6b7280;
            --confirmed: #22c55e;
            --needs-review: #eab308;
            --suppressed: #9ca3af;
            --bg: #f8fafc;
            --card-bg: #ffffff;
            --text: #1e293b;
            --text-muted: #64748b;
            --border: #e2e8f0;
        }}

        * {{
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }}

        body {{
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
            background: var(--bg);
            color: var(--text);
            line-height: 1.6;
        }}

        .container {{
            max-width: 1200px;
            margin: 0 auto;
            padding: 2rem;
        }}

        header {{
            background: linear-gradient(135deg, var(--primary), #3b82f6);
            color: white;
            padding: 3rem 2rem;
            margin-bottom: 2rem;
            border-radius: 0 0 1rem 1rem;
        }}

        header h1 {{
            font-size: 2rem;
            margin-bottom: 0.5rem;
        }}

        header .meta {{
            opacity: 0.9;
            font-size: 0.95rem;
        }}

        .summary-grid {{
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 1rem;
            margin-bottom: 2rem;
        }}

        .summary-card {{
            background: var(--card-bg);
            border-radius: 0.75rem;
            padding: 1.5rem;
            box-shadow: 0 1px 3px rgba(0,0,0,0.1);
        }}

        .summary-card h3 {{
            font-size: 0.875rem;
            color: var(--text-muted);
            text-transform: uppercase;
            letter-spacing: 0.05em;
            margin-bottom: 0.5rem;
        }}

        .summary-card .value {{
            font-size: 2rem;
            font-weight: 700;
        }}

        .risk-score {{
            background: {risk_color};
            color: white;
        }}

        .verification-summary {{
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            gap: 0.5rem;
            margin-top: 0.5rem;
        }}

        .verification-item {{
            text-align: center;
            padding: 0.5rem;
            border-radius: 0.5rem;
        }}

        .verification-item.confirmed {{ background: rgba(34, 197, 94, 0.1); color: var(--confirmed); }}
        .verification-item.needs-review {{ background: rgba(234, 179, 8, 0.1); color: var(--needs-review); }}
        .verification-item.suppressed {{ background: rgba(156, 163, 175, 0.1); color: var(--suppressed); }}

        .severity-breakdown {{
            display: flex;
            gap: 0.5rem;
            margin-top: 1rem;
        }}

        .severity-dot {{
            display: flex;
            align-items: center;
            gap: 0.25rem;
            font-size: 0.875rem;
        }}

        .severity-dot::before {{
            content: '';
            width: 12px;
            height: 12px;
            border-radius: 50%;
        }}

        .severity-dot.critical::before {{ background: var(--critical); }}
        .severity-dot.high::before {{ background: var(--high); }}
        .severity-dot.medium::before {{ background: var(--medium); }}
        .severity-dot.low::before {{ background: var(--low); }}
        .severity-dot.info::before {{ background: var(--info); }}

        .findings-section {{
            margin-bottom: 2rem;
        }}

        .section-header {{
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 1rem 1.5rem;
            background: var(--card-bg);
            border-radius: 0.75rem 0.75rem 0 0;
            border-bottom: 1px solid var(--border);
            cursor: pointer;
        }}

        .section-header h2 {{
            font-size: 1.25rem;
            display: flex;
            align-items: center;
            gap: 0.5rem;
        }}

        .section-header .count {{
            padding: 0.25rem 0.75rem;
            border-radius: 9999px;
            font-size: 0.875rem;
            font-weight: 600;
        }}

        .section-header.confirmed .count {{ background: var(--confirmed); color: white; }}
        .section-header.needs-review .count {{ background: var(--needs-review); color: white; }}
        .section-header.suppressed .count {{ background: var(--suppressed); color: white; }}

        .section-content {{
            background: var(--card-bg);
            border-radius: 0 0 0.75rem 0.75rem;
            padding: 1rem;
        }}

        .section-content.collapsed {{
            display: none;
        }}

        .toggle-icon {{
            transition: transform 0.2s;
        }}

        .collapsed .toggle-icon {{
            transform: rotate(-90deg);
        }}

        .finding {{
            background: var(--bg);
            border-radius: 0.75rem;
            padding: 1.5rem;
            margin-bottom: 1rem;
            border-left: 4px solid;
        }}

        .finding.critical {{ border-left-color: var(--critical); }}
        .finding.high {{ border-left-color: var(--high); }}
        .finding.medium {{ border-left-color: var(--medium); }}
        .finding.low {{ border-left-color: var(--low); }}
        .finding.info {{ border-left-color: var(--info); }}

        .finding h3 {{
            font-size: 1.125rem;
            margin-bottom: 0.75rem;
        }}

        .finding-meta {{
            display: flex;
            gap: 0.5rem;
            flex-wrap: wrap;
            margin-bottom: 1rem;
        }}

        .badge {{
            display: inline-block;
            padding: 0.25rem 0.75rem;
            border-radius: 9999px;
            font-size: 0.75rem;
            font-weight: 600;
            color: white;
        }}

        .badge.critical {{ background: var(--critical); }}
        .badge.high {{ background: var(--high); }}
        .badge.medium {{ background: var(--medium); }}
        .badge.low {{ background: var(--low); }}
        .badge.info {{ background: var(--info); }}

        .badge.source {{
            background: var(--primary);
        }}

        .badge.category {{
            background: var(--text-muted);
        }}

        .finding-details p {{
            margin-bottom: 0.5rem;
        }}

        .finding-details code {{
            background: var(--card-bg);
            padding: 0.125rem 0.375rem;
            border-radius: 0.25rem;
            font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
            font-size: 0.875rem;
        }}

        .evidence, .remediation, .ai-reasoning {{
            margin-top: 1rem;
            padding: 1rem;
            background: var(--card-bg);
            border-radius: 0.5rem;
        }}

        .evidence pre {{
            white-space: pre-wrap;
            word-wrap: break-word;
            font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
            font-size: 0.8rem;
            max-height: 300px;
            overflow-y: auto;
        }}

        .ai-reasoning {{
            border-left: 3px solid var(--primary);
        }}

        .tool-status {{
            background: var(--card-bg);
            border-radius: 0.75rem;
            padding: 1.5rem;
            margin-bottom: 2rem;
        }}

        .tool-status h3 {{
            margin-bottom: 1rem;
            font-size: 1rem;
            color: var(--text-muted);
        }}

        .tool-status-item {{
            display: flex;
            align-items: center;
            gap: 1rem;
            padding: 0.5rem 0;
            border-bottom: 1px solid var(--border);
        }}

        .tool-status-item:last-child {{
            border-bottom: none;
        }}

        .tool-name {{
            font-weight: 600;
            min-width: 120px;
        }}

        .tool-count {{
            color: var(--text-muted);
            font-size: 0.875rem;
        }}

        .tool-error {{
            color: var(--critical);
            font-size: 0.75rem;
        }}

        footer {{
            text-align: center;
            padding: 2rem;
            color: var(--text-muted);
            font-size: 0.875rem;
        }}

        @media print {{
            body {{ background: white; }}
            .container {{ max-width: 100%; }}
            .finding {{ break-inside: avoid; }}
            .section-content.collapsed {{ display: block !important; }}
        }}
    </style>
    <script>
        function toggleSection(sectionId) {{
            const content = document.getElementById(sectionId + '-content');
            const header = document.getElementById(sectionId + '-header');
            content.classList.toggle('collapsed');
            header.classList.toggle('collapsed');
        }}
    </script>
</head>
<body>
    <header>
        <div class="container">
            <h1>VAPT Security Assessment Report</h1>
            <div class="meta">
                <p><strong>Target:</strong> {_escape_html(data.target)}</p>
                <p><strong>Scan ID:</strong> {data.scan_id}</p>
                <p><strong>Date:</strong> {data.generated_at.strftime('%B %d, %Y at %H:%M UTC')}</p>
                <p><strong>Client:</strong> {_escape_html(data.config.client_name)} | <strong>Project:</strong> {_escape_html(data.config.project_name)}</p>
            </div>
        </div>
    </header>

    <div class="container">
        <section class="summary-grid">
            <div class="summary-card risk-score">
                <h3>Risk Rating</h3>
                <div class="value">{risk_rating}</div>
                <div style="font-size: 0.875rem; opacity: 0.9;">Score: {risk_score}/100</div>
            </div>

            <div class="summary-card">
                <h3>Total Findings</h3>
                <div class="value">{data.total_findings}</div>
                <div class="severity-breakdown">
                    <span class="severity-dot critical">{severity_counts['critical']}</span>
                    <span class="severity-dot high">{severity_counts['high']}</span>
                    <span class="severity-dot medium">{severity_counts['medium']}</span>
                    <span class="severity-dot low">{severity_counts['low']}</span>
                </div>
            </div>

            <div class="summary-card">
                <h3>Verification Status</h3>
                <div class="verification-summary">
                    <div class="verification-item confirmed">
                        <div style="font-size: 1.5rem; font-weight: 700;">{len(confirmed_findings)}</div>
                        <div style="font-size: 0.75rem;">Confirmed</div>
                    </div>
                    <div class="verification-item needs-review">
                        <div style="font-size: 1.5rem; font-weight: 700;">{len(needs_review_findings)}</div>
                        <div style="font-size: 0.75rem;">Needs Review</div>
                    </div>
                    <div class="verification-item suppressed">
                        <div style="font-size: 1.5rem; font-weight: 700;">{len(suppressed_findings)}</div>
                        <div style="font-size: 0.75rem;">Suppressed</div>
                    </div>
                </div>
            </div>

            <div class="summary-card">
                <h3>Pipeline Stats</h3>
                <div style="font-size: 0.875rem;">
                    <p>Raw: {canonical.summary.total_raw} → Deduped: {canonical.summary.after_dedup}</p>
                    <p>FP Rate: {((canonical.summary.suppressed_fp / canonical.summary.after_dedup * 100) if canonical.summary.after_dedup > 0 else 0):.1f}%</p>
                </div>
            </div>
        </section>

        <section class="tool-status">
            <h3>Tool Execution Status</h3>
            {tool_status_html if tool_status_html else '<p style="color: var(--text-muted);">No tool status available</p>'}
        </section>

        <section class="findings">
            {confirmed_html}
            {needs_review_html}
            {suppressed_html}
        </section>
    </div>

    <footer>
        <p>Generated by <strong>AIPTX</strong> - AI-Powered Penetration Testing Framework</p>
        <p>Pipeline Version: {canonical.pipeline_version} | Report generated on {data.generated_at.strftime('%Y-%m-%d %H:%M:%S UTC')}</p>
    </footer>
</body>
</html>"""

    return html


def _build_findings_section_v2(
    findings: list,
    title: str,
    section_id: str,
    include_evidence: bool = True,
    include_remediation: bool = True,
    include_ai_reasoning: bool = True,
    collapsed: bool = False,
) -> str:
    """Build HTML for a findings section"""
    from ..models.finding_v2 import SeverityV2

    if not findings:
        return ""

    severity_colors = {
        SeverityV2.CRITICAL: "#dc2626",
        SeverityV2.HIGH: "#ea580c",
        SeverityV2.MEDIUM: "#ca8a04",
        SeverityV2.LOW: "#2563eb",
        SeverityV2.INFO: "#6b7280",
    }

    findings_html = ""
    for i, finding in enumerate(findings, 1):
        color = severity_colors.get(finding.severity, "#6b7280")
        severity_class = finding.severity.value

        evidence_html = ""
        if finding.evidence and include_evidence:
            evidence_html = f"""
            <div class="evidence">
                <strong>Evidence:</strong>
                <pre>{_escape_html(finding.evidence[:2000])}</pre>
            </div>
            """

        remediation_html = ""
        if finding.remediation and include_remediation:
            remediation_html = f"""
            <div class="remediation">
                <strong>Remediation:</strong>
                <p>{_escape_html(finding.remediation)}</p>
            </div>
            """

        ai_html = ""
        if finding.ai_reasoning and include_ai_reasoning:
            ai_html = f"""
            <div class="ai-reasoning">
                <strong>AI Analysis:</strong>
                <p>{_escape_html(finding.ai_reasoning[:500])}</p>
            </div>
            """

        verification_badge = f"""
        <span class="badge" style="background: #6b7280;">
            {finding.verification_status.value.replace('_', ' ').title()}
        </span>
        """

        findings_html += f"""
        <div class="finding {severity_class}">
            <h3>{i}. {_escape_html(finding.title)}</h3>
            <div class="finding-meta">
                <span class="badge {severity_class}">{finding.severity.value.title()}</span>
                <span class="badge source">{_escape_html(finding.source_tool)}</span>
                <span class="badge category">{finding.category.value.replace('_', ' ').title()}</span>
                {verification_badge}
            </div>
            <div class="finding-details">
                <p><strong>URL:</strong> <code>{_escape_html(finding.url)}</code></p>
                {f'<p><strong>Parameter:</strong> <code>{_escape_html(finding.parameter)}</code></p>' if finding.parameter else ''}
                {f'<p><strong>Description:</strong> {_escape_html(finding.description)}</p>' if finding.description else ''}
                {evidence_html}
                {remediation_html}
                {ai_html}
            </div>
        </div>
        """

    collapsed_class = "collapsed" if collapsed else ""

    return f"""
    <div class="findings-section">
        <div id="{section_id}-header" class="section-header {section_id} {collapsed_class}" onclick="toggleSection('{section_id}')">
            <h2>
                <span class="toggle-icon">▼</span>
                {title}
            </h2>
            <span class="count">{len(findings)}</span>
        </div>
        <div id="{section_id}-content" class="section-content {collapsed_class}">
            {findings_html}
        </div>
    </div>
    """
