"""HTML dashboard report for yaml-doctor."""

from __future__ import annotations

import html as _html
from pathlib import Path

from ..models import Grade, LintResult, ScanResult, Severity
from ..utils import grade_color

_SEV_COLORS = {
    Severity.CRITICAL: "#ef4444",
    Severity.HIGH: "#f97316",
    Severity.MEDIUM: "#eab308",
    Severity.LOW: "#06b6d4",
    Severity.INFO: "#6b7280",
}

_GRADE_COLORS = {
    "green": "#22c55e",
    "yellow": "#eab308",
    "red": "#ef4444",
    "cyan": "#06b6d4",
}


def _css() -> str:
    return """
    :root {
        --bg: #0f172a; --surface: #1e293b; --border: #334155;
        --text: #e2e8f0; --muted: #94a3b8; --accent: #3b82f6;
    }
    * { box-sizing: border-box; margin: 0; padding: 0; }
    body { font-family: 'Segoe UI', system-ui, sans-serif; background: var(--bg); color: var(--text); padding: 2rem; }
    .container { max-width: 1100px; margin: 0 auto; }
    h1 { font-size: 1.8rem; margin-bottom: .5rem; }
    h2 { font-size: 1.3rem; margin: 1.5rem 0 .8rem; color: var(--accent); }
    .subtitle { color: var(--muted); margin-bottom: 1.5rem; }
    .cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 1rem; margin-bottom: 1.5rem; }
    .card { background: var(--surface); border: 1px solid var(--border); border-radius: .75rem; padding: 1.2rem; text-align: center; }
    .card .value { font-size: 2rem; font-weight: 700; }
    .card .label { color: var(--muted); font-size: .85rem; margin-top: .3rem; }
    table { width: 100%; border-collapse: collapse; margin-bottom: 1.5rem; }
    th { background: var(--surface); text-align: left; padding: .6rem .8rem; font-size: .8rem; text-transform: uppercase; color: var(--muted); border-bottom: 2px solid var(--border); }
    td { padding: .55rem .8rem; border-bottom: 1px solid var(--border); font-size: .9rem; }
    tr:hover td { background: rgba(59,130,246,.06); }
    .sev { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: .78rem; font-weight: 600; color: #fff; }
    .grade-badge { display: inline-block; font-size: 2.5rem; font-weight: 800; width: 72px; height: 72px; line-height: 72px; text-align: center; border-radius: 50%; }
    .score-bar { height: 8px; border-radius: 4px; background: var(--border); margin-top: .3rem; }
    .score-fill { height: 100%; border-radius: 4px; }
    .file-section { background: var(--surface); border: 1px solid var(--border); border-radius: .75rem; padding: 1.2rem; margin-bottom: 1rem; }
    .file-header { display: flex; align-items: center; gap: 1rem; margin-bottom: .8rem; }
    .file-header .path { font-family: monospace; font-size: .95rem; }
    .pass { color: #22c55e; } .fail { color: #ef4444; }
    .footer { text-align: center; color: var(--muted); font-size: .8rem; margin-top: 2rem; padding-top: 1rem; border-top: 1px solid var(--border); }
    """


def _sev_badge(sev: Severity) -> str:
    return f'<span class="sev" style="background:{_SEV_COLORS.get(sev, "#6b7280")}">{sev.value.upper()}</span>'


def _score_bar_html(score: int) -> str:
    col = "#22c55e" if score >= 80 else "#eab308" if score >= 60 else "#ef4444"
    return f'<div class="score-bar"><div class="score-fill" style="width:{score}%;background:{col}"></div></div>'


def _grade_badge(grade: Grade, score: int) -> str:
    gc = grade_color(grade)
    col = _GRADE_COLORS.get(gc, "#6b7280")
    return f'<span class="grade-badge" style="color:{col};border:3px solid {col}">{grade.value}</span>'


def _file_html(result: LintResult) -> str:
    gc = grade_color(result.grade)
    col = _GRADE_COLORS.get(gc, "#6b7280")
    status = "pass" if result.score >= 70 else "fail"

    if not result.valid_yaml:
        return f"""
        <div class="file-section" style="border-color:#ef4444">
            <div class="file-header">
                <span class="fail">✗</span>
                <span class="path">{_html.escape(result.file_path)}</span>
                <span class="fail">PARSE ERROR</span>
            </div>
            <p style="color:#ef4444">{_html.escape(result.parse_error or "Unknown error")}</p>
        </div>"""

    rows = ""
    for f in result.findings:
        rows += f"""<tr>
            <td>{_sev_badge(f.rule.severity)}</td>
            <td><b>{f.rule.rule_id}</b></td>
            <td>{f.line or '–'}</td>
            <td>{_html.escape(f.message)}</td>
            <td style="color:#22c55e">{_html.escape(f.rule.fix)}</td>
        </tr>"""

    table = ""
    if rows:
        table = f"""
        <table>
            <thead><tr><th>Severity</th><th>Rule</th><th>Line</th><th>Message</th><th>Fix</th></tr></thead>
            <tbody>{rows}</tbody>
        </table>"""
    else:
        table = '<p style="color:#22c55e;text-align:center">✓ No issues found — perfect!</p>'

    return f"""
    <div class="file-section">
        <div class="file-header">
            <span class="{status}" style="font-size:1.3rem;font-weight:700">{result.grade.value}</span>
            <span class="path">{_html.escape(result.file_path)}</span>
            <span style="color:{col}">{result.score}/100</span>
            <span style="color:var(--muted)">{result.file_type.value}</span>
        </div>
        {_score_bar_html(result.score)}
        {table}
    </div>"""


def export_file_html(result: LintResult, output_path: str) -> str:
    """Export single-file result to HTML."""
    body = _file_html(result)
    return _write(body, f"File Report — {result.file_path}", output_path)


def export_scan_html(scan: ScanResult, output_path: str) -> str:
    """Export directory scan to HTML dashboard."""
    # Summary cards
    cards = f"""
    <div class="cards">
        <div class="card">{_grade_badge(scan.overall_grade, scan.overall_score)}<div class="label">Overall Grade</div></div>
        <div class="card"><div class="value">{scan.overall_score}</div><div class="label">Score / 100</div></div>
        <div class="card"><div class="value">{scan.total_files}</div><div class="label">Files Scanned</div></div>
        <div class="card"><div class="value">{scan.total_findings}</div><div class="label">Total Findings</div></div>
        <div class="card"><div class="value" style="color:#22c55e">{scan.passed_files}</div><div class="label">Passed (A/A+)</div></div>
        <div class="card"><div class="value" style="color:#ef4444">{scan.failed_files}</div><div class="label">Failed (D/F)</div></div>
    </div>
    {_score_bar_html(scan.overall_score)}
    """

    # Severity breakdown
    crit = scan.critical_total
    high = scan.high_total
    med = sum(f.medium_count for f in scan.files)
    low = sum(f.low_count for f in scan.files)
    info = sum(f.info_count for f in scan.files)

    sev_cards = f"""
    <h2>Severity Breakdown</h2>
    <div class="cards">
        <div class="card"><div class="value" style="color:{_SEV_COLORS[Severity.CRITICAL]}">{crit}</div><div class="label">Critical</div></div>
        <div class="card"><div class="value" style="color:{_SEV_COLORS[Severity.HIGH]}">{high}</div><div class="label">High</div></div>
        <div class="card"><div class="value" style="color:{_SEV_COLORS[Severity.MEDIUM]}">{med}</div><div class="label">Medium</div></div>
        <div class="card"><div class="value" style="color:{_SEV_COLORS[Severity.LOW]}">{low}</div><div class="label">Low</div></div>
        <div class="card"><div class="value" style="color:{_SEV_COLORS[Severity.INFO]}">{info}</div><div class="label">Info</div></div>
    </div>
    """

    # File results
    files_html = "<h2>File Results</h2>\n"
    for result in scan.files:
        files_html += _file_html(result)

    body = cards + sev_cards + files_html
    return _write(body, "Scan Report", output_path)


def _write(body: str, title: str, output_path: str) -> str:
    """Write HTML to file."""
    page = f"""<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
    <title>yaml-doctor · {_html.escape(title)}</title>
    <style>{_css()}</style>
</head>
<body>
<div class="container">
    <h1>🩺 yaml-doctor</h1>
    <p class="subtitle">{_html.escape(title)}</p>
    {body}
    <div class="footer">Generated by yaml-doctor · YAML Linter &amp; Security Scanner</div>
</div>
</body>
</html>"""

    Path(output_path).parent.mkdir(parents=True, exist_ok=True)
    Path(output_path).write_text(page, encoding="utf-8")
    return output_path
