"""Audit check 4: small correctness probes on the chains and the wallet.

a. Does a clipped loss in `_steps_clipped` land exactly on -MAXDD (so `eq <= -MAXDD` fires), and a
   clipped win exactly on TARGET (so `eq >= TARGET` fires), in floating point? A miss leaves the
   account alive at the floor for one more trade, which the lattice chain never does.
b. Does `eval_chain` agree with `assess` (the rulebook Monte Carlo) at the deployed cell with both
   clips, on P(pass) and on mean trades? 5,000 accounts only.
c. Does `funded_chain` agree with `funded` (Monte Carlo) at the pick with the 7-trade clock? The
   module's `funded` reads WAIT from the module constant (14), so it is compared at wait 14.
d. The payout threshold and the 35% cap at the deployed cell, and the daily-rule margin.
e. The 3-day minimum and the clock: funded_chain has no MIN_DAYS term; it is inert only while wait >= 3.

    cd /root/Projects/trading-framework && python3 /tmp/arena-prime-audit/candidate-2/c2_floats.py
"""
import json
import sys

import numpy as np

sys.path.insert(0, "/root/Projects/trading-framework")
from src.notebooks.reports.topics.prime_academy.modules import prime as PA  # noqa: E402

DEC = json.load(open("/root/Projects/trading-framework/src/notebooks/reports/topics/prime_academy/paper/decision.json"))
G = DEC["scenarios"]["random side, swap charged"]["cost"]
RF = DEC["scenarios"]["random side, swap charged"]["pick"]["risk"]

# a. landing exactness
rng = np.random.default_rng(0)
n = 200_000
eq = rng.uniform(-0.09, 0.09, n)
r, c = 0.03, G * 0.03
a = np.minimum(np.full(n, r), np.maximum(PA.TARGET - eq + c, 1e-12))
b = np.minimum(np.full(n, r), np.maximum(eq + PA.MAXDD - c, 1e-12))
clip_up = a < r; clip_dn = b < r
eq_win = eq + a - c; eq_loss = eq - b - c
miss_up = clip_up & ~(eq_win >= PA.TARGET)
miss_dn = clip_dn & ~(eq_loss <= -PA.MAXDD)
print(f"[a] clipped wins that miss TARGET by rounding: {miss_up.sum()} of {clip_up.sum()} "
      f"(largest shortfall {np.max(PA.TARGET - eq_win[clip_up]) if clip_up.any() else 0:.2e}); "
      f"clipped losses that miss -MAXDD: {miss_dn.sum()} of {clip_dn.sum()} (largest {np.max(eq_loss[clip_dn] + PA.MAXDD) if clip_dn.any() else 0:.2e})")

# b. eval_chain against assess, both clips, 5,000 accounts
e = PA.eval_chain(0.03, c, rr=1.0, clip_up=True, clip_dn=True)
m = PA.assess(0.03, c, n=5000, seed=5, rr=1.0, clip_up=True, clip_dn=True, paths=True)
se = np.sqrt(e["p_pass"] * (1 - e["p_pass"]) / 5000)
days = m["paths"]["days"]
print(f"[b] eval_chain P(pass) {e['p_pass']:.4f}, E[trades] {e['e_trades']:.3f}; assess (5,000) P(pass) {m['p_pass']:.4f} "
      f"({(m['p_pass'] - e['p_pass']) / se:+.2f} SE), mean trades {days.mean():.3f}; chain median {e['med_trades']}, MC median {np.median(days):.0f}")

# c. funded_chain against funded (MC reads the module WAIT = 14): compare at wait 14
f14 = PA.funded_chain(RF, G * RF, PA.payout_threshold(RF, 1.0, 3000, 0.7), rr=1.0, clip_dn=True, wait=14)
mc = PA.funded(RF, G * RF, 0.7, 100 / 0.7 / 3000, n=5000, seed=11, rr=1.0, clip_dn=True)
se = np.sqrt(f14["p_any"] * (1 - f14["p_any"]) / 5000)
print(f"[c] wait 14: funded_chain p_any {f14['p_any']:.4f} e_W {f14['e_W']:.4f} e_life {f14['e_life']:.1f}; "
      f"funded MC (5,000) p_any {mc['p_any']:.4f} ({(mc['p_any'] - f14['p_any']) / se:+.2f} SE) gross {mc['gross']:.4f} life {mc['e_trades']:.1f}")
f7 = PA.funded_chain(RF, G * RF, PA.payout_threshold(RF, 1.0, 3000, 0.7), rr=1.0, clip_dn=True, wait=7)
print(f"    wait 7: p_any {f7['p_any']:.4f} e_W {f7['e_W']:.4f} e_life {f7['e_life']:.1f} med_first_pay {f7['med_first_pay']} "
      f"(x 2.03 d = {f7['med_first_pay'] * 2.03:.0f} calendar days; the paper's Table 2 quotes the broker's 46 days at a 14-TRADE clock)")

# d. thresholds at the deployed cell
m_req = PA.payout_threshold(RF, 1.0, 3000, 0.7)
print(f"[d] payout threshold at rf {RF:.5f}: max(100/0.7/3000 = {100 / 0.7 / 3000:.4f}, rf/0.35 = {RF / 0.35:.4f}) = {m_req:.4f} of bankroll; "
      f"35%-cap on the assessment win: 0.35 x 0.09 = {0.35 * 0.09:.4f} >= 3% gross win: {0.03 <= 0.35 * 0.09}; "
      f"daily rule at one trade: loss {0.03 * (1 + G):.4f} against 5% of (1 - D) = {0.05 * 0.91:.4f}")

# e. the lattice resolution of the risk at the pick
units = PA._units(G * RF, None)
print(f"[e] funded_chain lattice: units {units:.0f} per bankroll, risk rounds to {round(RF * units) / units:.6f} (asked {RF}), "
      f"cost to {round(G * RF * units) / units:.7f} (asked {G * RF:.7f}); eval_chain units {PA._units(c, None):.0f}")
