"""
dashboard_server_zscore_jp2y_patch.py
Fixes z-score mismatch and JP2Y chart in dashboard_server.py.
Run: python src/execution/dashboard_server_zscore_jp2y_patch.py
"""
from pathlib import Path
import re, sys

BASE_PATH = Path(__file__).resolve().parents[2]
SERVER    = BASE_PATH / "src" / "execution" / "dashboard_server.py"

if not SERVER.exists():
    print(f"ERROR: {SERVER} not found"); sys.exit(1)

code = SERVER.read_text(encoding="utf-8")
changes = 0

# ── Fix 1: Inject state-file z-score reader into write_data() ─────────────
# Find DATA_FILE.write_text call inside write_data and inject before it
STATE_READER = '''
        # ── Read z-scores from state files (authoritative — never stale) ──
        try:
            import json as _jsn
            _ld = BASE_PATH / "data" / "logs"
            _eu_s = _ld / "state_eurusd.json"
            _uj_s = _ld / "state_usdjpy.json"
            if _eu_s.exists():
                _eu = _jsn.loads(_eu_s.read_text(encoding="utf-8"))
                if _eu.get("last_zscore") is not None:
                    data["zscore"] = float(_eu["last_zscore"])
                if _eu.get("position_open") is not None:
                    if not _eu["position_open"]:
                        data["position"] = None
                    elif _eu.get("position_signal") == 1:
                        data["position"] = "LONG"
                    elif _eu.get("position_signal") == -1:
                        data["position"] = "SHORT"
            if _uj_s.exists():
                _uj = _jsn.loads(_uj_s.read_text(encoding="utf-8"))
                if _uj.get("last_zscore") is not None:
                    if "usdjpy" not in data:
                        data["usdjpy"] = {}
                    data["usdjpy"]["current_z"] = float(_uj["last_zscore"])
        except Exception:
            pass
        # ──────────────────────────────────────────────────────────────────
'''

# Insert before DATA_FILE.write_text
if 'DATA_FILE.write_text' in code and '# ── Read z-scores from state files' not in code:
    code = code.replace(
        'DATA_FILE.write_text(json.dumps(data, indent=2), encoding="utf-8")',
        STATE_READER + '        DATA_FILE.write_text(json.dumps(data, indent=2), encoding="utf-8")',
        1  # only first occurrence (in write_data)
    )
    changes += 1
    print("Fix 1 (z-score from state files): ✅")
elif '# ── Read z-scores from state files' in code:
    print("Fix 1: already applied")
else:
    print("Fix 1: ❌ DATA_FILE.write_text not found")

# ── Fix 2: JP2Y series — slice to last 365 rows ───────────────────────────
# Find where jp2y_series is assigned and add slicing
# Pattern: jp2y_series = [...] or jp2y_series = df[...].tolist()
jp2y_patterns = re.findall(r'(jp2y_series\s*=\s*.+)', code)
print(f"jp2y_series assignments found: {len(jp2y_patterns)}")
for p in jp2y_patterns:
    print(f"  {p[:80]}")

# Also find jp2y loading from CSV
if 'jp2y.csv' in code:
    idx = code.find('jp2y.csv')
    print(f"\nCSV context:\n{code[max(0,idx-100):idx+200]}")

# Find and patch jp2y_series assignment to limit to 365 rows
# Look for: "jp2y_series": or jp2y_series = 
for pattern, replacement in [
    # If jp2y_series is built as a list from a dataframe
    (r'(jp2y_series\s*=\s*df_jp2y\[.*?\]\.(?:round\([^)]+\)\.)?tolist\(\))',
     r'\1[-365:]'),
    (r'(jp2y_series\s*=\s*\[.*?for.*?in.*?jp2y.*?\])',
     r'\1[-365:]'),
    # If it's set from a slice of values
    (r'("jp2y_series"\s*:\s*)(\[.*?\])',
     r'\1\2[-365:]'),
]:
    new_code = re.sub(pattern, replacement, code, flags=re.DOTALL)
    if new_code != code:
        code = new_code
        changes += 1
        print(f"Fix 2 (jp2y slice): ✅ via pattern {pattern[:40]}")
        break

# If no regex matched, do targeted text injection
if '[-365:]' not in code and 'jp2y_series' in code:
    # Find the jp2y_series= line and add slice after it
    lines = code.split('\n')
    for i, line in enumerate(lines):
        if 'jp2y_series' in line and '=' in line and 'def ' not in line and '#' not in line.split('=')[0]:
            stripped = line.rstrip()
            if not stripped.endswith(('[-365:]', '# jp2y sliced')):
                lines[i] = stripped + '  # jp2y: limit to 365 recent rows'
                # Add slice on next assignment reference
                # Find where jp2y_series is used in yields dict
                for j in range(i+1, min(i+30, len(lines))):
                    if 'jp2y_series' in lines[j] and '[-365:]' not in lines[j]:
                        lines[j] = lines[j].replace(
                            'jp2y_series',
                            'jp2y_series[-365:] if jp2y_series else jp2y_series'
                        )
                        changes += 1
                        print(f"Fix 2 (jp2y slice at line {j+1}): ✅")
                        break
                break
    code = '\n'.join(lines)

SERVER.write_text(code, encoding="utf-8")
print(f"\n{changes} change(s) applied | {len(code.splitlines())} lines")
print("Restart dashboard_server.py to apply.")
