"""Tests du câblage des 7 toggles « Données à détecter » → moteur (Plan 1b / P1-2).

Sémantique UI : un toggle ON = « détecter cette catégorie » (= masquer).
Un toggle OFF = la catégorie est laissée en clair → elle entre dans
``disabled_kinds`` (set des CATÉGORIES désactivées passé au moteur).

Aucun widget, aucun display : on teste l'état (ConfigState) et le pont
(build_engine_kwargs / make_process_fn) en pur Python.
"""

from __future__ import annotations

from pathlib import Path

from gui_v6.config_state import (
    CATEGORY_FIELDS,
    DETECTION_CATEGORIES,
    ConfigState,
)
from gui_v6.engine_bridge import (
    EngineSettings,
    NerManagers,
    build_engine_kwargs,
    make_process_fn,
)


# -- catégories canoniques -------------------------------------------------

def test_seven_categories_match_engine_set():
    # Les 7 catégories exposées doivent matcher EXACTEMENT le set moteur.
    assert set(DETECTION_CATEGORIES) == {
        "NOM",
        "DATE_NAISSANCE",
        "ETAB",
        "ADRESSE",
        "NIR",
        "TEL",
        "ADHERENT",
    }
    # Un champ booléen par catégorie.
    assert set(CATEGORY_FIELDS.values()) == set(DETECTION_CATEGORIES)


# -- disabled_kinds dérivé -------------------------------------------------

def test_disabled_kinds_empty_by_default():
    # Défaut : tous les toggles ON ⇒ aucun désactivé (zéro changement vs aujourd'hui).
    state = ConfigState()
    assert state.disabled_kinds() == frozenset()


def test_disabled_kinds_unchecking_nir_and_etab():
    # Décocher « N° sécurité sociale » (NIR) et « Établissements » (ETAB).
    state = ConfigState(detect_nir=False, detect_etab=False)
    assert state.disabled_kinds() == frozenset({"NIR", "ETAB"})


def test_disabled_kinds_all_off():
    state = ConfigState(
        detect_nom=False,
        detect_date_naissance=False,
        detect_etab=False,
        detect_adresse=False,
        detect_nir=False,
        detect_tel=False,
        detect_adherent=False,
    )
    assert state.disabled_kinds() == frozenset(DETECTION_CATEGORIES)


# -- propagation vers EngineSettings --------------------------------------

def test_to_engine_settings_propagates_disabled_kinds():
    state = ConfigState(detect_nir=False, detect_tel=False)
    settings = state.to_engine_settings()
    assert settings.disabled_kinds == frozenset({"NIR", "TEL"})


def test_to_engine_settings_default_empty():
    settings = ConfigState().to_engine_settings()
    assert settings.disabled_kinds == frozenset()


# -- propagation dans les kwargs moteur -----------------------------------

def test_build_engine_kwargs_includes_disabled_kinds():
    settings = EngineSettings(disabled_kinds=frozenset({"NIR", "ETAB"}))
    kwargs = build_engine_kwargs(settings, managers=None)
    assert kwargs["disabled_kinds"] == frozenset({"NIR", "ETAB"})


def test_build_engine_kwargs_default_empty_disabled_kinds():
    # Défaut (set vide) = no-op : la clé est présente mais vide.
    kwargs = build_engine_kwargs(EngineSettings(), managers=None)
    assert kwargs["disabled_kinds"] == frozenset()


def test_process_fn_threads_disabled_kinds_to_engine(tmp_path):
    settings = EngineSettings(
        use_local_ner=False, disabled_kinds=frozenset({"ADRESSE"})
    )
    managers = NerManagers(settings)
    captured = {}

    def fake_engine(doc_path, out_dir, **kwargs):
        captured["kwargs"] = kwargs
        return {"status": "ok"}

    fn = make_process_fn(settings, managers=managers, engine=fake_engine)
    fn(tmp_path / "doc.pdf", tmp_path / "out")
    assert captured["kwargs"]["disabled_kinds"] == frozenset({"ADRESSE"})


# -- bout-en-bout : ConfigState → settings → kwargs -----------------------

def test_end_to_end_state_to_kwargs(tmp_path):
    state = ConfigState(detect_adherent=False)
    settings = state.to_engine_settings(config_path=Path("/tmp/c.yml"))
    kwargs = build_engine_kwargs(settings, managers=None)
    assert kwargs["disabled_kinds"] == frozenset({"ADHERENT"})
