#!/usr/bin/env python3
"""Normalize XAUUSD backtest JSON files to the canonical JOURNAL_SCHEMA.md."""
from __future__ import annotations
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
DATA = ROOT / "data"
STRATEGIES = [
    "Aryy HTF Narrative Fib 50/62",
    "ICT Sweep + MSS + FVG",
    "Order Block Reclaim",
    "Liquidity Sweep Reversal",
    "Breaker Continuation",
]
SESSIONS = ["Asia", "London", "NY AM", "London Close", "NY PM"]


def load(path: Path):
    if not path.exists():
        return {}
    return json.loads(path.read_text())


def as_list(obj, key):
    if isinstance(obj, list):
        return obj
    if isinstance(obj, dict):
        return obj.get(key, []) or []
    return []


def trade_key(t):
    return str(t.get("id") or "|".join(map(str, [t.get("date", ""), t.get("strategy", ""), t.get("direction", ""), t.get("entry", ""), t.get("stop", ""), t.get("target", "")])) )


def norm_trade(t, idx):
    return {
        "id": t.get("id", idx),
        "date": str(t.get("date") or (str(t.get("timestamp", ""))[:10] if t.get("timestamp") else "")),
        "timestamp": str(t.get("timestamp", "")),
        "symbol": t.get("symbol") or t.get("pair") or "XAUUSD",
        "strategy": t.get("strategy", "Unclassified"),
        "direction": t.get("direction", ""),
        "session": t.get("session", ""),
        "narrative": t.get("narrative") or t.get("narrative_htf", ""),
        "htf_context": t.get("htf_context") or t.get("narrative_htf", ""),
        "ltf_trigger": t.get("ltf_trigger") or t.get("narrative_ltf", ""),
        "entry": float(t.get("entry", t.get("entry_price", 0)) or 0),
        "stop": float(t.get("stop", t.get("sl_price", t.get("stop_loss", 0))) or 0),
        "target": float(t.get("target", t.get("tp_price", t.get("take_profit", 0))) or 0),
        "fib": t.get("fib") or t.get("fib_alignment") or "N/A",
        "pd": t.get("pd") or t.get("pd_array") or "N/A",
        "outcome": t.get("outcome", ""),
        "r": float(t.get("r", t.get("pnl_r", 0)) or 0),
        "confidence": t.get("confidence", ""),
        "notes": t.get("notes") or t.get("reason") or t.get("narrative_ltf") or "",
    }


def norm_shadow(s, idx):
    return {
        "id": s.get("id", f"shadow_{idx}"),
        "date": str(s.get("date") or (str(s.get("timestamp", ""))[:10] if s.get("timestamp") else "")),
        "timestamp": str(s.get("timestamp", "")),
        "symbol": s.get("symbol") or s.get("pair") or "XAUUSD",
        "type": s.get("type") or ("Paper win" if str(s.get("outcome", "")).lower() == "win" else s.get("outcome", "Observed")),
        "strategy": s.get("strategy", ""),
        "direction": s.get("direction", ""),
        "entry": float(s.get("entry", s.get("entry_price", 0)) or 0),
        "stop": float(s.get("stop", s.get("sl_price", s.get("stop_loss", 0))) or 0),
        "target": float(s.get("target", s.get("tp_price", s.get("take_profit", 0))) or 0),
        "r": float(s.get("r", s.get("pnl_r", 0)) or 0),
        "note": s.get("note") or s.get("notes") or s.get("reason") or "",
    }


def dedupe(rows):
    out = {}
    for r in rows:
        out[trade_key(r)] = r
    return list(out.values())


def main():
    journal_path = DATA / "journal.json"
    backtest_path = DATA / "backtest-data.json"
    shadow_path = DATA / "shadow-trades.json"

    journal = load(journal_path)
    backtest = load(backtest_path)
    shadow = load(shadow_path)

    trades_raw = as_list(journal, "trades") + as_list(backtest, "trades")
    trades = dedupe([norm_trade(t, i + 1) for i, t in enumerate(trades_raw)])
    for i, t in enumerate(trades, 1):
        t["id"] = i

    shadow_rows = [norm_shadow(s, i + 1) for i, s in enumerate(as_list(shadow, "shadowTrades"))]

    base_meta = {
        "symbol": "XAUUSD",
        "mode": "manual_tradingview_replay",
        "period": "2026-01-01 to 2026-07-17",
        "currency": "USD",
        "riskPerR": 100,
        "startingBalance": 10000,
        "isDummy": False,
        "source": "manual_tradingview_replay_confirmed",
    }
    confirmed_obj = {"metadata": base_meta, "strategies": STRATEGIES, "sessions": SESSIONS, "trades": trades}
    journal_path.write_text(json.dumps(confirmed_obj, indent=2, ensure_ascii=False) + "\n")
    backtest_path.write_text(json.dumps(confirmed_obj, indent=2, ensure_ascii=False) + "\n")

    shadow_obj = {
        "metadata": {
            "symbol": "XAUUSD",
            "mode": "manual_tradingview_replay_shadow_entries",
            "period": "2026-01-01 to 2026-07-17",
            "isDummy": False,
            "source": "manual_tradingview_replay_observed",
        },
        "shadowTrades": shadow_rows,
    }
    shadow_path.write_text(json.dumps(shadow_obj, indent=2, ensure_ascii=False) + "\n")
    print(f"normalized confirmed={len(trades)} shadow={len(shadow_rows)}")

if __name__ == "__main__":
    main()
