from __future__ import annotations

import textwrap
from pathlib import Path

import pytest

from csvkit_py.tools.profile import profile, splittable


@pytest.fixture
def sample(tmp_path: Path) -> Path:
    """Miniature d'un export Mangools : un identifiant, un axe, une mesure, un vide."""
    path = tmp_path / "in.csv"
    path.write_text(
        textwrap.dedent("""\
            Keyword,Location,Volume,Notes
            a,United States,1300,
            b,Germany,880,
            c,United States,720,
            d,Germany,,
            e,United States,90,
            f,Germany,140,
            """),
        encoding="utf-8",
    )
    return path


def test_profile_counts_fill_and_cardinality(sample: Path):
    by_name = {r["colonne"]: r for r in profile(sample).to_dicts()}

    assert by_name["Location"]["rempli"] == 6
    assert by_name["Location"]["rempli_%"] == 100.0
    assert by_name["Location"]["distinctes"] == 2

    # Une cellule vide ne compte ni comme remplie ni comme valeur distincte.
    assert by_name["Volume"]["rempli"] == 5
    assert by_name["Volume"]["distinctes"] == 5


def test_empty_column_is_not_counted_as_filled(sample: Path):
    by_name = {r["colonne"]: r for r in profile(sample).to_dicts()}
    assert by_name["Notes"]["rempli"] == 0
    assert by_name["Notes"]["rempli_%"] == 0.0
    assert by_name["Notes"]["num_%"] == 0.0


def test_numeric_share_separates_measures_from_categories(sample: Path):
    by_name = {r["colonne"]: r for r in profile(sample).to_dicts()}
    assert by_name["Volume"]["num_%"] == 100.0
    assert by_name["Location"]["num_%"] == 0.0


def test_unique_share_flags_identifier_columns(sample: Path):
    by_name = {r["colonne"]: r for r in profile(sample).to_dicts()}
    assert by_name["Keyword"]["unique_%"] == 100.0
    assert by_name["Location"]["unique_%"] == pytest.approx(33.3)


def test_splittable_keeps_only_the_real_axis(sample: Path):
    kept = splittable(profile(sample))["colonne"].to_list()

    assert kept == ["Location"], "Volume est une mesure, Keyword un identifiant, Notes est vide"


def test_splittable_ranks_best_filled_first(tmp_path: Path):
    path = tmp_path / "in.csv"
    path.write_text(
        textwrap.dedent("""\
            Plein,Creux
            fr,a
            en,a
            fr,b
            en,b
            fr,a
            en,b
            fr,
            en,
            """),
        encoding="utf-8",
    )

    kept = splittable(profile(path))["colonne"].to_list()
    assert kept == ["Plein", "Creux"], "la colonne la mieux remplie doit sortir en tête"
