"""Smoke test: simulates what a real user would do after pip install geood.

No mocks, no internals, no fixtures. Just the public API.
Must verify that results are MEANINGFUL, not just that the API doesn't crash.
"""

import os
import tempfile


def test_user_journey():
    """A user installs geood, calibrates, detects, saves, loads, detects again."""
    import geood
    from transformers import AutoConfig, AutoModelForCausalLM, AutoTokenizer

    # User has a model
    config = AutoConfig.from_pretrained("gpt2")
    config.n_layer = 4
    config.n_embd = 128
    config.n_head = 4
    config.n_inner = 256
    model = AutoModelForCausalLM.from_config(config)
    tokenizer = AutoTokenizer.from_pretrained("gpt2")

    # User calibrates
    ref_texts = [f"This is reference sentence number {i}." for i in range(30)]
    detector = geood.calibrate(model, ref_texts, tokenizer=tokenizer)

    # User inspects
    assert repr(detector).startswith("Detector(")
    assert detector.layer_used is not None
    # Layer 0 should NOT be selected when deeper layers are available
    assert detector.layer_used > 0, (
        f"Auto-select chose layer 0 (embeddings). Expected a deeper layer."
    )

    # User detects single
    result = detector.detect("Hello world.", model=model, tokenizer=tokenizer)
    assert hasattr(result, "is_ood")
    assert hasattr(result, "score")
    assert hasattr(result, "explain")
    assert 0.0 <= result.score <= 1.0
    explanation = result.explain()
    assert isinstance(explanation, str)
    assert len(explanation) > 0

    # CRITICAL: calibration texts must be classified as in-distribution
    ref_result = detector.detect(ref_texts[0], model=model, tokenizer=tokenizer)
    assert ref_result.score < 0.9, (
        f"Calibration text classified as OOD (score={ref_result.score:.3f}). "
        "Detector is broken — own reference texts should be in-distribution."
    )

    # User detects batch
    results = detector.detect(
        ["One text.", "Another text.", "Third text."],
        model=model, tokenizer=tokenizer,
    )
    assert len(results) == 3
    for r in results:
        assert 0.0 <= r.score <= 1.0
        assert r.intrinsic_dim is not None  # batch provides dim

    # User saves and loads
    with tempfile.TemporaryDirectory() as d:
        detector.save(os.path.join(d, "my_detector"))
        loaded = geood.load(os.path.join(d, "my_detector"))
        assert repr(loaded).startswith("Detector(")

        # User detects with loaded detector
        r2 = loaded.detect("Hello world.", model=model, tokenizer=tokenizer)
        assert abs(result.score - r2.score) < 1e-6


def test_empty_ref_texts_raises():
    """Empty ref_texts should raise ValueError, not crash with numpy errors."""
    import geood
    from transformers import AutoConfig, AutoModelForCausalLM, AutoTokenizer
    import pytest

    config = AutoConfig.from_pretrained("gpt2")
    config.n_layer = 4
    config.n_embd = 128
    config.n_head = 4
    config.n_inner = 256
    model = AutoModelForCausalLM.from_config(config)
    tokenizer = AutoTokenizer.from_pretrained("gpt2")

    with pytest.raises(ValueError, match="at least 2 texts"):
        geood.calibrate(model, [], tokenizer=tokenizer)
