"""`engine._check_pending_fill` — ordnet eine gefüllte Stop-Order dem Bot zu.

HINTERGRUND (2026-08-06): eine ruhende Stop-Order füllt IM BROKER, nicht über
`engine._open`. `trader._refresh_locked` adoptiert die Position dann per
magic-match und loggt sie OHNE `setup` — vier reale Squeeze-Trades waren dadurch
von manuellen nicht unterscheidbar, und B4-Monitor, `squeeze_b5` sowie
`squeeze_entry_gap` zählten **null**. Deployment-Drift Fall 8: nicht die Strategie
driftete, sondern ihre Beobachtbarkeit.

Die Zuordnung ist eindeutig, weil bei einem Pending-Fill die POSITIONS-Nummer
identisch mit der ORDER-Nummer ist (an allen vier Broker-Datensätzen verifiziert).
"""


def test_squeeze_fill_wird_getaggt(engine):
    engine._pending_tickets = {49483981: "squeeze"}
    engine.trader.snap = {"ticket": 49483981, "order_type": 1,
                          "entry_price": 75.127}
    engine._check_pending_fill()

    assert engine._squeeze_entry_count == 1
    assert engine._bot_open_ticket == 49483981
    assert engine._bot_open_source == "auto_squeeze"
    assert 49483981 not in engine._pending_tickets     # Merker verbraucht


def test_unbekannte_quelle_wird_NICHT_getaggt(engine):
    """⚠ Ersetzt `test_signal_fill_long` (der Auto-Signal-Pfad ist am
    2026-08-12 entfernt). Der Test wurde NICHT geloescht, sondern umgedreht:
    seit es nur noch den Squeeze gibt, darf ein Fill mit einer FREMDEN Quelle
    nicht stillschweigend als Squeeze durchgehen — das waere genau
    Deployment-Drift Fall 8 (vier reale Trades landeten als `setup=NULL` und
    waren von manuellen nicht unterscheidbar), nur mit umgekehrtem Vorzeichen:
    ein Fremd-Trade wuerde die B4-/B5-Monitore verfaelschen."""
    engine._pending_tickets = {777: "signal"}          # Altbestand / unbekannt
    engine.trader.snap = {"ticket": 777, "order_type": 0, "entry_price": 75.2}
    engine._check_pending_fill()

    assert engine._squeeze_entry_count == 0
    assert engine._bot_open_source is None
    # ⚠ Der Merker bleibt STEHEN — nur ein sauber zugeordneter Fill verbraucht
    #   ihn. So wird derselbe Fall beim naechsten Tick erneut gemeldet, statt
    #   still zu verschwinden.
    assert 777 in engine._pending_tickets


def test_fremde_position_wird_nicht_getaggt(engine):
    """Der gefährliche Fall: ein manueller Trade darf NICHT als Bot-Trade gelten —
    sonst verfälscht er genau die Monitore, die der Fix reparieren soll."""
    engine._pending_tickets = {111: "squeeze"}
    engine.trader.snap = {"ticket": 999, "order_type": 0, "entry_price": 75.0}
    engine._check_pending_fill()

    assert engine._squeeze_entry_count == 0
    assert engine._bot_open_ticket is None
    assert engine._pending_tickets == {111: "squeeze"}   # bleibt liegen


def test_derselbe_fill_zaehlt_nur_einmal(engine):
    """Der `_pos_loop` läuft im Sekundentakt — ohne Dedup zählte ein Trade
    hundertfach und der B4-Monitor wäre wertlos."""
    engine._pending_tickets = {222: "squeeze"}
    engine.trader.snap = {"ticket": 222, "order_type": 1, "entry_price": 74.9}
    for _ in range(5):
        engine._check_pending_fill()

    assert engine._squeeze_entry_count == 1


def test_flat_ist_ein_no_op(engine):
    engine._pending_tickets = {333: "squeeze"}
    engine.trader.snap = {"ticket": None}
    engine._check_pending_fill()

    assert engine._squeeze_entry_count == 0
    assert engine._pending_tickets == {333: "squeeze"}


def test_ohne_pending_merker_sofort_raus(engine):
    """Der häufigste Fall — es darf keine DB-Arbeit anfallen."""
    engine.trader.snap = {"ticket": 444, "order_type": 0}
    engine._check_pending_fill()

    assert engine._bot_open_ticket is None
