import pandas as pd
from pathlib import Path
import sys

BASE_PATH = Path(__file__).resolve().parents[2]
SRC_PATH = BASE_PATH / "src"

if str(SRC_PATH) not in sys.path:
    sys.path.append(str(SRC_PATH))

from ingestion.price_loader import load_eurusd
from features.yield_spreads import build_spread_features

# Use the coefficients we just estimated from the 24H regression
BETA_2Y = -0.0162
BETA_10Y = -0.0071


def build_spot_lag_v2():
    prices = load_eurusd().copy()
    spreads = build_spread_features().copy()

    spread_cols = [
        "date",
        "spread_2y",
        "spread_10y",
        "spread_2y_change_1d",
        "spread_2y_change_5d",
        "spread_2y_zscore_20d",
        "spread_10y_change_1d",
        "spread_10y_change_5d",
        "spread_10y_zscore_20d",
    ]
    spreads = spreads[spread_cols].copy()

    # Keep hourly bars in EET
    prices["date"] = prices["datetime"].dt.normalize()

    # Merge daily spread features onto hourly bars
    df = prices.merge(spreads, on="date", how="left")

    fill_cols = [c for c in spread_cols if c != "date"]
    df[fill_cols] = df[fill_cols].ffill()

    # Spot returns
    df["eurusd_return_24h"] = df["close"].pct_change(24)
    df["eurusd_return_48h"] = df["close"].pct_change(48)

    # Predicted EURUSD move from rates
    df["predicted_return_24h"] = (
        BETA_2Y * df["spread_2y_change_1d"] +
        BETA_10Y * df["spread_10y_change_1d"]
    )

    # Core lag: what rates imply vs what spot has done
    df["lag_gap_24h"] = df["predicted_return_24h"] - df["eurusd_return_24h"]

    # Rolling normalization to create a tradable score
    lag_mean = df["lag_gap_24h"].rolling(60, min_periods=60).mean()
    lag_std = df["lag_gap_24h"].rolling(60, min_periods=60).std()

    df["lag_zscore_24h"] = (df["lag_gap_24h"] - lag_mean) / lag_std

    # Directional interpretation
    # Positive lag_zscore => EURUSD underperformed vs rates-implied move
    # Negative lag_zscore => EURUSD outperformed vs rates-implied move
    df["signal_direction"] = 0
    df.loc[df["lag_zscore_24h"] > 1.0, "signal_direction"] = 1
    df.loc[df["lag_zscore_24h"] < -1.0, "signal_direction"] = -1

    return df


def get_model_ready_spot_lag_v2():
    df = build_spot_lag_v2().copy()

    required_cols = [
        "close",
        "spread_2y_change_1d",
        "spread_10y_change_1d",
        "eurusd_return_24h",
        "predicted_return_24h",
        "lag_gap_24h",
        "lag_zscore_24h",
    ]

    model_df = df.dropna(subset=required_cols).reset_index(drop=True)
    return model_df


if __name__ == "__main__":
    raw_df = build_spot_lag_v2()
    model_df = get_model_ready_spot_lag_v2()

    cols_to_show = [
        "datetime",
        "close",
        "spread_2y_change_1d",
        "spread_10y_change_1d",
        "eurusd_return_24h",
        "predicted_return_24h",
        "lag_gap_24h",
        "lag_zscore_24h",
        "signal_direction",
    ]

    print("\nMODEL-READY SAMPLE:")
    print(model_df[cols_to_show].head(10))
    print(model_df[cols_to_show].tail(10))

    print("\nRows:", len(model_df))
    print("Date range:", model_df["datetime"].min(), "to", model_df["datetime"].max())

    print("\nSignal counts:")
    print(model_df["signal_direction"].value_counts(dropna=False).sort_index())