"""Tests des écarts d'inventaire calculés depuis parts_filtered.csv."""

import csv
from pathlib import Path

from lib.rebrickable.inventory_reconciliation import (
    compute_inventory_gaps,
    index_sets_by_num,
    write_inventory_gaps_csv,
    write_inventory_gaps_markdown,
)


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


def test_compute_inventory_gaps_excludes_spares(tmp_path: Path) -> None:
    """Ignore les pièces de rechange et ne conserve que les sets en écart."""
    sets_path = tmp_path / "sets_enriched.csv"
    parts_path = tmp_path / "parts_filtered.csv"
    write_csv(
        sets_path,
        ["set_num", "set_id", "num_parts", "in_collection"],
        [
            ["1000-1", "1000", "4", "true"],
            ["2000-1", "2000", "3", "false"],
            ["3000-1", "3000", "1", "true"],
        ],
    )
    write_csv(
        parts_path,
        ["part_num", "color_rgb", "is_translucent", "set_num", "set_id", "quantity_in_set", "is_spare"],
        [
            ["A", "AAAAAA", "false", "1000-1", "1000", "2", "false"],
            ["B", "BBBBBB", "false", "1000-1", "1000", "2", "false"],
            ["S", "SSSSSS", "false", "1000-1", "1000", "5", "true"],
            ["C", "CCCCCC", "false", "2000-1", "2000", "2", "false"],
            ["D", "DDDDDD", "false", "3000-1", "3000", "1", "false"],
        ],
    )

    gaps = compute_inventory_gaps(sets_path, parts_path)

    assert gaps == [
        {
            "set_num": "1000-1",
            "set_id": "1000",
            "expected_parts": 4,
            "inventory_parts": 9,
            "inventory_parts_non_spare": 4,
            "delta": 5,
            "delta_non_spare": 0,
            "in_collection": "true",
        },
        {
            "set_num": "2000-1",
            "set_id": "2000",
            "expected_parts": 3,
            "inventory_parts": 2,
            "inventory_parts_non_spare": 2,
            "delta": 1,
            "delta_non_spare": 1,
            "in_collection": "false",
        }
    ]


def test_write_inventory_gaps_csv(tmp_path: Path) -> None:
    """Sérialise le rapport d'écarts dans un CSV dédié."""
    destination_path = tmp_path / "inventory_gaps.csv"
    rows = [
        {
            "set_num": "2000-1",
            "set_id": "2000",
            "expected_parts": 3,
            "inventory_parts": 2,
            "inventory_parts_non_spare": 2,
            "delta": 1,
            "delta_non_spare": 1,
            "in_collection": "false",
        }
    ]

    write_inventory_gaps_csv(destination_path, rows)

    with destination_path.open() as csv_file:
        written_rows = list(csv.DictReader(csv_file))

    assert written_rows == [
        {
            "set_num": "2000-1",
            "set_id": "2000",
            "expected_parts": "3",
            "inventory_parts": "2",
            "inventory_parts_non_spare": "2",
            "delta": "1",
            "delta_non_spare": "1",
            "in_collection": "false",
        }
    ]


def test_write_inventory_gaps_markdown(tmp_path: Path) -> None:
    """Produit un tableau Markdown listant les sets en écart."""
    destination_path = tmp_path / "inventory_gaps.md"
    gaps = [
        {
            "set_num": "2000-1",
            "set_id": "2000",
            "expected_parts": 3,
            "inventory_parts": 2,
            "inventory_parts_non_spare": 2,
            "delta": 1,
            "delta_non_spare": 1,
            "in_collection": "false",
        }
    ]
    sets = [
        {
            "set_num": "2000-1",
            "set_id": "2000",
            "num_parts": "3",
            "name": "Test Set",
            "year": "2020",
            "rebrickable_url": "https://rebrickable.com/sets/2000-1",
            "in_collection": "false",
        }
    ]

    write_inventory_gaps_markdown(destination_path, gaps, index_sets_by_num(sets))

    with destination_path.open() as markdown_file:
        content = markdown_file.read().splitlines()

    assert content[0].startswith("| set_id | name |")
    assert (
        "| [2000](https://rebrickable.com/sets/2000-1) | Test Set | 2020 | 1 | 1 | 3 | 2 | 2 | false | [PDF](https://www.lego.com/service/buildinginstructions/2000) |"
        in content
    )
