import pytest

from app.services.infra.database import bootstrap_tenant
from app.services.pairing.decisions import (
    APPROVAL_THRESHOLD, is_servable, load, record,
)


def pair(confidence=0.9, source="embedding"):
    return {"anchor_key": "a", "neighbor_key": "b", "pair_type": "similar",
            "confidence": confidence, "source": source}


def test_a_confident_pair_is_servable_without_approval():
    assert is_servable(pair(confidence=APPROVAL_THRESHOLD), None) is True


def test_an_unsure_pair_is_not_servable_until_approved():
    assert is_servable(pair(confidence=0.2), None) is False
    assert is_servable(pair(confidence=0.2), "approved") is True


def test_a_rejected_pair_is_never_servable_however_confident():
    # A merchant saying no is information the scorer does not have.
    assert is_servable(pair(confidence=0.99), "rejected") is False


def test_a_merchant_declared_pair_never_queues():
    assert is_servable(pair(confidence=0.0, source="merchant"), None) is True


def test_decisions_round_trip(temp_tenant):
    bootstrap_tenant(temp_tenant)
    assert record(temp_tenant, [
        {"anchor_key": "a", "neighbor_key": "b", "pair_type": "similar",
         "decision": "approved", "decided_by": "someone@example.com"}]) == 1
    assert load(temp_tenant)[("a", "b", "similar")] == "approved"


def test_a_decision_can_be_changed(temp_tenant):
    bootstrap_tenant(temp_tenant)
    base = {"anchor_key": "a", "neighbor_key": "b", "pair_type": "similar"}
    record(temp_tenant, [dict(base, decision="approved")])
    record(temp_tenant, [dict(base, decision="rejected")])
    assert load(temp_tenant)[("a", "b", "similar")] == "rejected"


def test_a_batch_is_recorded_in_one_call(temp_tenant):
    # A merchant clearing a queue decides many pairs in one sitting.
    bootstrap_tenant(temp_tenant)
    assert record(temp_tenant, [
        {"anchor_key": "a", "neighbor_key": f"b{i}", "pair_type": "similar",
         "decision": "approved"} for i in range(5)]) == 5


def test_an_invalid_decision_is_refused(temp_tenant):
    bootstrap_tenant(temp_tenant)
    with pytest.raises(ValueError):
        record(temp_tenant, [{"anchor_key": "a", "neighbor_key": "b",
                              "pair_type": "similar", "decision": "maybe"}])


def test_a_decision_survives_for_a_pair_that_does_not_exist_yet(temp_tenant):
    # A re-run may recreate a pair, and the decision must already be waiting.
    bootstrap_tenant(temp_tenant)
    record(temp_tenant, [{"anchor_key": "ghost", "neighbor_key": "x",
                          "pair_type": "similar", "decision": "rejected"}])
    assert load(temp_tenant)[("ghost", "x", "similar")] == "rejected"
