from __future__ import annotations

import pandas as pd


def detect_discontinuities(frame: pd.DataFrame, threshold: float = 0.35) -> pd.DataFrame:
    rows: list[dict[str, object]] = []
    for symbol, group in frame.sort_values(["symbol", "date"]).groupby("symbol", sort=False):
        previous = group["close"].shift(1)
        returns = group["close"] / previous - 1
        for index in group.index[returns.abs() > threshold]:
            rows.append({
                "symbol": symbol, "date": group.at[index, "date"],
                "previous_close": float(previous.at[index]), "current_close": float(group.at[index, "close"]),
                "return": float(returns.at[index]), "status": "REQUIRES_REVIEW",
                "possible_causes": "corporate action; bad data; genuine move",
            })
    return pd.DataFrame(rows)


def reconcile_discontinuities(
    discontinuities: pd.DataFrame, corporate_actions: pd.DataFrame, window_days: int = 3
) -> pd.DataFrame:
    if discontinuities.empty:
        return discontinuities.assign(action_match=pd.Series(dtype="boolean"))
    result = discontinuities.copy()
    result["action_match"] = False
    result["matched_action"] = pd.NA
    if corporate_actions.empty:
        return result
    for index, row in result.iterrows():
        candidates = corporate_actions[corporate_actions["symbol"] == row["symbol"]]
        distance = (pd.to_datetime(candidates["action_date"]) - pd.Timestamp(row["date"])).dt.days.abs()
        matches = candidates[distance <= window_days]
        if not matches.empty:
            result.at[index, "action_match"] = True
            result.at[index, "matched_action"] = str(matches.iloc[0]["action_type"])
    return result
