"""
dashboard_server_final_patch.py
================================
Comprehensive fix for all remaining dashboard server issues.

Fixes:
  1. EU outlook — filter Japan events OUT (only US/DE/EU)
  2. UJ outlook — Japan events now score correctly (was passing wrong filter)
  3. SOFR series — add sofr_series to fetch_yield_data() for chart
  4. JP2Y series — already handled, verify it's there

Run on VPS:
  python src\\execution\\dashboard_server_final_patch.py
"""
from pathlib import Path
import ast

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

def patch():
    code = SERVER_FILE.read_text(encoding="utf-8")
    changes = 0

    # ── PATCH 1: Fix _score_te_event — separate EU scoring from JP ────────────
    # The EU scorer should NOT score Japan events (they leak into EU outlook)
    # Add a "eu_only" flag so get_weekly_outlook can call it with EU filter
    old_score_fn = """def _score_te_event(event):
    country    = event.get("Country","").lower()
    category   = event.get("Category","").lower()
    importance = int(event.get("Importance", 1))
    is_us = "united states" in country
    is_de = "germany" in country
    is_eu = "euro" in country
    is_jp = "japan" in country

    if not (is_us or is_de or is_eu or is_jp):
        return 0"""

    new_score_fn = """def _score_te_event(event, eu_only=False):
    country    = event.get("Country","").lower()
    category   = event.get("Category","").lower()
    importance = int(event.get("Importance", 1))
    is_us = "united states" in country
    is_de = "germany" in country
    is_eu = "euro" in country
    is_jp = "japan" in country

    # eu_only=True used by EURUSD outlook — excludes Japan events
    if eu_only and is_jp:
        return 0

    if not (is_us or is_de or is_eu or is_jp):
        return 0"""

    if "eu_only=False" not in code:
        if old_score_fn in code:
            code = code.replace(old_score_fn, new_score_fn)
            changes += 1
            print("  ✅ Patch 1: Added eu_only flag to _score_te_event")
        else:
            print("  ⚠️  Patch 1: Could not find _score_te_event — check manually")
    else:
        print("  ⏭  Patch 1: Already applied")

    # ── PATCH 2: Fix get_weekly_outlook to pass eu_only=True ─────────────────
    old_eu_score = "        score = _score_te_event(e)"
    new_eu_score = "        score = _score_te_event(e, eu_only=True)"

    # Only replace inside get_weekly_outlook — find the function context
    # The function has a specific structure we can target
    if "eu_only=True" not in code:
        # Count occurrences to be safe
        if code.count(old_eu_score) == 1:
            code = code.replace(old_eu_score, new_eu_score)
            changes += 1
            print("  ✅ Patch 2: EU outlook now filters Japan events")
        elif code.count(old_eu_score) > 1:
            # Multiple occurrences — need to be careful
            # Only replace the one in get_weekly_outlook
            eu_fn_start = code.find("def get_weekly_outlook(")
            eu_fn_end   = code.find("\ndef get_usdjpy", eu_fn_start)
            if eu_fn_end == -1:
                eu_fn_end = code.find("\ndef _recalc_probs", eu_fn_start)
            eu_fn_block = code[eu_fn_start:eu_fn_end]
            new_eu_block = eu_fn_block.replace(old_eu_score, new_eu_score, 1)
            code = code[:eu_fn_start] + new_eu_block + code[eu_fn_end:]
            changes += 1
            print("  ✅ Patch 2: EU outlook filtered (multi-occurrence case)")
        else:
            print("  ⚠️  Patch 2: _score_te_event call not found in get_weekly_outlook")
    else:
        print("  ⏭  Patch 2: Already applied")

    # ── PATCH 3: Add sofr_series to fetch_yield_data ─────────────────────────
    old_sofr_end = """    if "us2y_daily" in yields and "sofr_daily" in yields:
        yields["sofr_vs_2y"] = round(
            yields["us2y_daily"] - yields["sofr_daily"], 3)

    return yields"""

    new_sofr_end = """    if "us2y_daily" in yields and "sofr_daily" in yields:
        yields["sofr_vs_2y"] = round(
            yields["us2y_daily"] - yields["sofr_daily"], 3)

    # ── Build sofr_series for chart ──────────────────────────────────────────
    try:
        import csv as _csv
        sofr_path = BASE_PATH / "data" / "raw" / "rates" / "sofr.csv"
        if sofr_path.exists():
            rows = [r for r in _csv.reader(open(sofr_path))
                    if len(r) == 2 and r[1] not in (".", "", "VALUE")]
            rows = rows[-90:]  # last 90 days
            yields["sofr_series"] = [float(r[1]) for r in rows]
            yields["sofr_times"]  = [r[0] for r in rows]
    except Exception:
        pass

    return yields"""

    if "sofr_series" not in code:
        if old_sofr_end in code:
            code = code.replace(old_sofr_end, new_sofr_end)
            changes += 1
            print("  ✅ Patch 3: Added sofr_series to fetch_yield_data")
        else:
            print("  ⚠️  Patch 3: Could not find sofr end block")
    else:
        print("  ⏭  Patch 3: sofr_series already present")

    # ── PATCH 4: Verify jp2y_series is present (from previous patch) ─────────
    if "jp2y_series" in code:
        print("  ✅ Patch 4: jp2y_series already present")
    else:
        print("  ⚠️  Patch 4: jp2y_series missing — re-run usdjpy_inline_patch")

    # ── Write ─────────────────────────────────────────────────────────────────
    if changes > 0:
        try:
            ast.parse(code)
        except SyntaxError as e:
            print(f"  ❌ Syntax error: {e}")
            return False
        SERVER_FILE.write_text(code, encoding="utf-8")
        print(f"\n  ✅ dashboard_server.py patched ({changes} changes)")
    else:
        print("\n  ✅ No new changes needed")
    return True

if __name__ == "__main__":
    print("=" * 60)
    print("DASHBOARD SERVER — Final Comprehensive Patch")
    print("=" * 60)
    patch()
    print("\n  Restart dashboard_server.py to apply.")
