"""Fehlbuchung beim Schliessen: darf nicht entstehen — und muss korrigierbar sein.

ANLASS (2026-08-12, User: „ueberpruefe ob Tag P/L richtig berechnet wird").
Ergebnis: die FORMEL war richtig, die DATENBASIS nicht — Anzeige +14,26 EUR
gegen −74,08 EUR realisiert beim Broker.

⚠⚠ URSACHE, im Log im Sekundentakt sichtbar (#49926460):
    20:04:10  SELL 1.64L eroeffnet
    20:04:10  „Position extern geschlossen"        <- 0 Sekunden spaeter
    20:04:12  „kein OUT-Deal in 1 Deals"
    20:04:12  Fallback-PnL 0,00 gebucht
    20:11:42  der ECHTE Close — lief ins Leere
Drei Defekte griffen ineinander:
  (1) `positions_get` sieht die frische Position einen Tick lang nicht,
  (2) `_log_external_close` bucht TROTZ „kein OUT-Deal" einen Close,
  (3) `log_trade_close` fasst nur `exit_time IS NULL` an → die Fehlbuchung
      blockiert den echten Close dauerhaft.
Bei #49852362 kostete das **+5,87 statt −95,38 EUR** und buchte den Trade auf
den FALSCHEN TAG.
"""
from __future__ import annotations

import time

import pytest

# Zeitstempel MUESSEN nach der Eroeffnung liegen: `log_trade_close` schiebt
# ein exit VOR dem entry defensiv auf `jetzt` (sonst waere die Haltedauer
# negativ). Mit 1000/2000 misst man diese Defensive, nicht den Fix.
_T1 = int(time.time()) + 10
_T2 = int(time.time()) + 20


def test_fehlbuchung_wird_von_echtem_close_korrigiert(history):
    """Defekt (3): eine `unknown`-Zeile darf der Wahrheit nicht im Weg stehen."""
    history.log_trade_open(ticket=4711, symbol="SpotCrude", direction="SELL",
                        lots=1.64, entry_price=83.162)
    # Fehlbuchung, wie der Fallback sie schrieb
    history.log_trade_close(ticket=4711, exit_price=0.0, pnl=0.0,
                         closed_by="unknown", exit_ts=_T1)
    # der ECHTE Close mit Deal-Daten
    history.log_trade_close(ticket=4711, exit_price=83.056, pnl=15.08,
                         closed_by="manual", exit_ts=_T2)

    t = history.trade_by_ticket(4711)
    assert t["pnl"] == 15.08, "der echte Close muss die Fehlbuchung ersetzen"
    assert t["closed_by"] == "manual"
    assert t["exit_price"] == 83.056
    assert t["exit_time"] == _T2, "auch der TAG muss korrigiert werden"


def test_gute_zeile_wird_NICHT_ueberschrieben(history):
    """⚠ Die Gegenprobe — sonst waere der Fix schlimmer als der Fehler.
    Ein sauber gebuchter Close ist endgueltig."""
    history.log_trade_open(ticket=4712, symbol="SpotCrude", direction="BUY",
                        lots=1.0, entry_price=80.0)
    history.log_trade_close(ticket=4712, exit_price=81.0, pnl=100.0,
                         closed_by="sl", exit_ts=_T1)
    history.log_trade_close(ticket=4712, exit_price=99.9, pnl=-999.0,
                         closed_by="manual", exit_ts=_T2)

    t = history.trade_by_ticket(4712)
    assert t["pnl"] == 100.0 and t["closed_by"] == "sl" and t["exit_time"] == _T1


def test_unknown_ersetzt_nicht_unknown(history):
    """Eine zweite Fehlbuchung darf die erste nicht ueberschreiben — sonst
    wandert der Zeitstempel bei jedem Tick weiter und der Trade landet
    irgendwann auf einem beliebigen Tag."""
    history.log_trade_open(ticket=4713, symbol="SpotCrude", direction="BUY",
                        lots=1.0, entry_price=80.0)
    history.log_trade_close(ticket=4713, exit_price=0.0, pnl=0.0,
                         closed_by="unknown", exit_ts=_T1)
    history.log_trade_close(ticket=4713, exit_price=0.0, pnl=5.0,
                         closed_by="unknown", exit_ts=_T2)

    t = history.trade_by_ticket(4713)
    assert t["exit_time"] == _T1 and t["pnl"] == 0.0


def test_offener_trade_bleibt_offen_ohne_close(history):
    """Grundinvariante: ohne Close-Buchung keine exit_time — sonst zaehlt ein
    laufender Trade in den Tages-P&L."""
    history.log_trade_open(ticket=4714, symbol="SpotCrude", direction="BUY",
                        lots=1.0, entry_price=80.0)
    t = history.trade_by_ticket(4714)
    assert t["exit_time"] is None and t["pnl"] is None


if __name__ == "__main__":
    raise SystemExit(pytest.main([__file__, "-v"]))
