#!/usr/bin/env python3
"""
patch_v3_snapshot.py
====================
PATCH B (standalone) - snapshot grouping position-query fallback.

Fixes the JSON=8 vs MT5=7 display mismatch: update_account_snapshot groups
deals from the date-range query, which sometimes omits an exit deal on IC
Markets demo. For any position with <2 deals, re-fetch via the reliable
position-specific query.

This standalone version matches on a single distinctive line to avoid the
whitespace-sensitivity that stopped the combined patcher.

Usage:  python patch_v3_snapshot.py
"""
import sys, shutil, ast
from pathlib import Path

candidates = [
    Path(r"C:\Users\paul_\OneDrive\fx_macro_intraday\src\execution\live_signal_monitor_v3.py"),
    Path(r"C:\Users\Administrator\OneDrive\fx_macro_intraday\src\execution\live_signal_monitor_v3.py"),
    Path(__file__).parent / "live_signal_monitor_v3.py",
]
target = next((p for p in candidates if p.exists()), None)
if target is None:
    print("ERROR: could not find live_signal_monitor_v3.py")
    sys.exit(1)
print(f"Target file: {target}")

backup = target.with_suffix(".py.backup_snapshot")
if not backup.exists():
    shutil.copy2(target, backup)
    print(f"Backup created: {backup}")
else:
    print(f"Backup already exists: {backup}")

content = target.read_text(encoding="utf-8")

# Already applied?
if "Augment incomplete positions" in content:
    print("PATCH B skipped: already applied (found marker comment).")
    sys.exit(0)

# Find the anchor line by searching line-by-line (tolerant of leading
# whitespace), then insert the fallback block right before it with matching
# indentation. Anchor: the mt5_pair_pnl initialisation inside
# update_account_snapshot.
lines = content.splitlines(keepends=True)
anchor_idx = None
for i, ln in enumerate(lines):
    if 'mt5_pair_pnl' in ln and '{"EURUSD": 0.0' in ln:
        anchor_idx = i
        break

if anchor_idx is None:
    print("ERROR: could not find mt5_pair_pnl anchor line. Aborting.")
    sys.exit(2)

# Determine indentation of the anchor line
anchor_line = lines[anchor_idx]
indent = anchor_line[:len(anchor_line) - len(anchor_line.lstrip())]

# Build the insertion block with the same indentation
block = (
    f"{indent}# Augment incomplete positions (date-range query sometimes omits\n"
    f"{indent}# the exit deal on IC Markets demo - 2026-06-01 root cause). For\n"
    f"{indent}# any position with <2 deals, re-fetch via the position query.\n"
    f"{indent}for (_sym, _pid), _dl in list(by_position.items()):\n"
    f"{indent}    if len(_dl) < 2:\n"
    f"{indent}        _ps = mt5.history_deals_get(position=_pid)\n"
    f"{indent}        if _ps and len(_ps) > len(_dl):\n"
    f"{indent}            by_position[(_sym, _pid)] = [d for d in _ps\n"
    f"{indent}                                         if d.symbol == _sym]\n"
)

lines.insert(anchor_idx, block)
content = "".join(lines)

try:
    ast.parse(content)
    print("Syntax check: OK")
except SyntaxError as e:
    print(f"ERROR: syntax error after patch: {e}. Aborting, no changes written.")
    sys.exit(3)

target.write_text(content, encoding="utf-8")
print("PATCH B applied: snapshot grouping uses position-query fallback")
print(f"\nSUCCESS: patched {target}")
print("\nNext: restart v3. Snapshot should show matching JSON/MT5 counts")
print("(no more 'using JSON counts (JSON=8 vs MT5=7)' warning).")
