"""Tests du calcul des pièces rares."""

import csv
from pathlib import Path

from lib.rebrickable.rare_parts import build_rare_parts, write_rare_parts_by_set, write_rare_parts_list


def write_csv(path: Path, headers: list[str], rows: list[list[str]]) -> None:
    """Écrit un CSV simple pour les besoins de tests."""
    with path.open("w", newline="") as csv_file:
        writer = csv.writer(csv_file)
        writer.writerow(headers)
        writer.writerows(rows)


def test_build_rare_parts_detects_exclusive_variations(tmp_path: Path) -> None:
    """Identifie les combinaisons pièce+couleur présentes dans un seul set."""
    parts_filtered = tmp_path / "parts_filtered.csv"
    write_csv(
        parts_filtered,
        [
            "part_num",
            "color_rgb",
            "is_translucent",
            "set_num",
            "set_id",
            "year",
            "quantity_in_set",
            "is_spare",
            "is_minifig_part",
        ],
        [
            ["p1", "AAAAAA", "false", "1000-1", "1000", "2020", "2", "false", "false"],
            ["p1", "AAAAAA", "false", "2000-1", "2000", "2021", "3", "false", "false"],
            ["p2", "BBBBBB", "false", "1000-1", "1000", "2020", "1", "false", "true"],
            ["p3", "CCCCCC", "true", "2000-1", "2000", "2021", "4", "false", "false"],
        ],
    )
    sets_enriched = tmp_path / "sets_enriched.csv"
    write_csv(
        sets_enriched,
        ["set_num", "set_id", "name", "year", "in_collection"],
        [
            ["1000-1", "1000", "Set A", "2020", "true"],
            ["2000-1", "2000", "Set B", "2021", "false"],
        ],
    )
    parts_catalog = tmp_path / "parts.csv"
    write_csv(
        parts_catalog,
        ["part_num", "name", "part_cat_id"],
        [
            ["p1", "Brick 1x1", "1"],
            ["p2", "Head Custom", "59"],
            ["p3", "Slope 45", "2"],
        ],
    )
    colors = tmp_path / "colors.csv"
    write_csv(
        colors,
        ["id", "name", "rgb", "is_trans", "num_parts", "num_sets", "y1", "y2"],
        [
            ["1", "Gray", "AAAAAA", "false", "0", "0", "0", "0"],
            ["2", "Blue", "BBBBBB", "false", "0", "0", "0", "0"],
            ["3", "Trans-Clear", "CCCCCC", "true", "0", "0", "0", "0"],
        ],
    )

    rare_parts, rare_by_set = build_rare_parts(parts_filtered, sets_enriched, parts_catalog, colors)

    assert rare_parts == [
        {
            "set_num": "1000-1",
            "set_id": "1000",
            "set_name": "Set A",
            "year": "2020",
            "part_num": "p2",
            "part_name": "Head Custom",
            "part_cat_id": "59",
            "color_rgb": "BBBBBB",
            "color_name": "Blue",
            "is_translucent": "false",
            "is_minifig_part": "true",
            "quantity_in_set": "1",
            "in_collection": "true",
        },
        {
            "set_num": "2000-1",
            "set_id": "2000",
            "set_name": "Set B",
            "year": "2021",
            "part_num": "p3",
            "part_name": "Slope 45",
            "part_cat_id": "2",
            "color_rgb": "CCCCCC",
            "color_name": "Trans-Clear",
            "is_translucent": "true",
            "is_minifig_part": "false",
            "quantity_in_set": "4",
            "in_collection": "false",
        },
    ]
    assert rare_by_set == [
        {
            "set_num": "1000-1",
            "set_id": "1000",
            "name": "Set A",
            "year": "2020",
            "in_collection": "true",
            "rare_parts_distinct": "1",
            "rare_parts_quantity": "1",
            "rare_minifig_parts_distinct": "1",
            "rare_minifig_quantity": "1",
        },
        {
            "set_num": "2000-1",
            "set_id": "2000",
            "name": "Set B",
            "year": "2021",
            "in_collection": "false",
            "rare_parts_distinct": "1",
            "rare_parts_quantity": "4",
            "rare_minifig_parts_distinct": "0",
            "rare_minifig_quantity": "0",
        },
    ]


def test_write_rare_parts_outputs_csv(tmp_path: Path) -> None:
    """Sérialise les pièces rares et l’agrégat par set."""
    rare_parts_path = tmp_path / "rare_parts.csv"
    rare_by_set_path = tmp_path / "rare_parts_by_set.csv"
    rare_parts_sample = [
        {
            "set_num": "123-1",
            "set_id": "123",
            "set_name": "Sample",
            "year": "2020",
            "part_num": "p1",
            "part_name": "Brick",
            "part_cat_id": "1",
            "color_rgb": "FFFFFF",
            "color_name": "White",
            "is_translucent": "false",
            "is_minifig_part": "false",
            "quantity_in_set": "2",
            "in_collection": "true",
        }
    ]
    rare_by_set_sample = [
        {
            "set_num": "123-1",
            "set_id": "123",
            "name": "Sample",
            "year": "2020",
            "in_collection": "true",
            "rare_parts_distinct": "1",
            "rare_parts_quantity": "2",
            "rare_minifig_parts_distinct": "0",
            "rare_minifig_quantity": "0",
        }
    ]

    write_rare_parts_list(rare_parts_path, rare_parts_sample)
    write_rare_parts_by_set(rare_by_set_path, rare_by_set_sample)

    assert rare_parts_path.exists()
    assert rare_by_set_path.exists()
