"""Visualisation de la part des têtes jaunes sur le catalogue global."""

from pathlib import Path
from typing import Dict, List

import matplotlib.pyplot as plt

from lib.filesystem import ensure_parent_dir
from lib.milestones import load_milestones
from lib.rebrickable.stats import read_rows


def compute_yellow_share(rows: List[dict]) -> List[dict]:
    """Calcule la part de la couleur Yellow par année."""
    aggregated: Dict[str, Dict[str, int]] = {}
    for row in rows:
        year = row["year"]
        if year not in aggregated:
            aggregated[year] = {"yellow": 0, "total": 0}
        aggregated[year]["total"] += int(row["quantity"])
        if row["color_name"].lower() == "yellow" or row["color_rgb"].upper() == "FFFF00":
            aggregated[year]["yellow"] += int(row["quantity"])
    results = []
    for year in sorted(aggregated.keys(), key=int):
        total = aggregated[year]["total"]
        yellow = aggregated[year]["yellow"]
        share = yellow / total if total > 0 else 0
        results.append({"year": int(year), "yellow_share": share, "total": total})
    return results


def plot_yellow_share(heads_path: Path, milestones_path: Path, destination_path: Path) -> None:
    """Trace l'évolution de la part de têtes jaunes dans le catalogue complet."""
    rows = read_rows(heads_path)
    milestones = load_milestones(milestones_path)
    series = compute_yellow_share(rows)
    years = [item["year"] for item in series]
    shares = [item["yellow_share"] for item in series]

    fig, ax = plt.subplots(figsize=(13, 5.5))
    ax.plot(years, shares, color="#f2c300", marker="o", linewidth=2.4, label="Part Yellow")
    ax.fill_between(years, shares, color="#f2c300", alpha=0.18)
    ax.set_ylim(0, min(1.0, max(shares + [0.01]) * 1.1))
    ax.set_ylabel("Part de têtes Yellow")
    ax.set_xlabel("Année")
    if len(years) > 15:
        step = max(1, len(years) // 10)
        ax.set_xticks(years[::step])
    else:
        ax.set_xticks(years)
    ax.set_title("Evolution de l'usage des têtes Yellow (catalogue complet)")
    ax.grid(True, linestyle="--", alpha=0.3)
    if milestones:
        min_year = min(years)
        max_year = max(years)
        milestones_in_range = sorted(
            [m for m in milestones if min_year <= m["year"] <= max_year],
            key=lambda m: (m["year"], m["description"]),
        )
        offset_map: Dict[int, int] = {}
        offset_step = 0.35
        top_limit = ax.get_ylim()[1] * 1.05
        for milestone in milestones_in_range:
            year = milestone["year"]
            count_for_year = offset_map.get(year, 0)
            offset_map[year] = count_for_year + 1
            horizontal_offset = offset_step * (count_for_year // 2 + 1)
            if count_for_year % 2 == 1:
                horizontal_offset *= -1
            text_x = year + horizontal_offset
            ax.axvline(year, color="#d62728", linestyle="--", linewidth=1, alpha=0.65, zorder=1)
            ax.text(
                text_x,
                top_limit,
                milestone["description"],
                rotation=90,
                verticalalignment="top",
                horizontalalignment="center",
                fontsize=8,
                color="#d62728",
            )
        ax.set_ylim(ax.get_ylim()[0], top_limit * (1 + max(offset_map.values(), default=0) * 0.02))
    ensure_parent_dir(destination_path)
    fig.tight_layout()
    fig.savefig(destination_path, dpi=170)
    plt.close(fig)
