from __future__ import annotations

import json
from typing import Any

from aicd.tools import viz_assets


def series_to_chartjs_config(
    chart_type: str,
    labels: list[str],
    values: list[Any],
    *,
    dataset_label: str = "Series",
) -> dict[str, Any]:
    """Build a Chart.js config object (JSON-serializable)."""
    ct = (chart_type or "bar").strip().lower()
    if ct not in ("bar", "line"):
        ct = "bar"
    nums = [float(v) for v in values]
    ds: dict[str, Any] = {
        "label": dataset_label,
        "data": nums,
        "backgroundColor": "rgba(78, 121, 167, 0.6)",
        "borderColor": "rgba(78, 121, 167, 1)",
        "borderWidth": 1,
    }
    if ct == "line":
        ds["fill"] = False
        ds["tension"] = 0.2
    return {
        "type": ct,
        "data": {
            "labels": list(labels),
            "datasets": [ds],
        },
        "options": {
            "responsive": True,
            "plugins": {"legend": {"display": bool(dataset_label)}},
        },
    }


def series_to_chartjs_config_json(
    chart_type: str,
    labels: list[str],
    values: list[Any],
    *,
    dataset_label: str = "Series",
) -> str:
    return json.dumps(
        series_to_chartjs_config(chart_type, labels, values, dataset_label=dataset_label),
        ensure_ascii=False,
    )


def mermaid_bar_from_counts(labels: list[str], counts: list[int]) -> str:
    """Simple text bar chart (not Mermaid syntax; ASCII bars for logs)."""
    if len(labels) != len(counts):
        return ""
    mx = max(counts) if counts else 1
    mx = max(mx, 1)
    lines: list[str] = []
    w = max(len(str(lbl)) for lbl in labels) if labels else 0
    for lbl, c in zip(labels, counts):
        bar_w = min(40, int(40 * c / mx))
        lines.append(f"{str(lbl).ljust(w)} | {'#' * bar_w} {c}")
    return "\n".join(lines)


def chart_body_and_script(
    chart_type: str,
    labels: list[str],
    values: list[Any],
    *,
    dataset_label: str = "Series",
    canvas_id: str = "aicd-data-chart",
) -> tuple[str, str]:
    cfg = series_to_chartjs_config(
        chart_type, labels, values, dataset_label=dataset_label
    )
    cfg_js = json.dumps(cfg, ensure_ascii=False)
    body = f'<section><h2>Chart</h2><canvas id="{canvas_id}" width="800" height="400"></canvas></section>'
    extra_scripts = f"""
<script>
(function () {{
  var cfg = {cfg_js};
  var el = document.getElementById("{canvas_id}");
  if (el && window.Chart) {{
    new Chart(el.getContext("2d"), cfg);
  }}
}})();
</script>
"""
    return body, extra_scripts


def build_html_with_chart(
    title: str,
    chart_type: str,
    labels: list[str],
    values: list[Any],
    *,
    dataset_label: str = "Series",
    canvas_id: str = "aicd-data-chart",
) -> str:
    """Full HTML document with local ./res Chart.js (caller copies res via viz_assets)."""
    body, extra = chart_body_and_script(
        chart_type,
        labels,
        values,
        dataset_label=dataset_label,
        canvas_id=canvas_id,
    )
    return viz_assets.build_viz_html_document(
        title,
        body,
        extra_scripts=extra,
        include_default_chart_vis_init=False,
    )
