"""Pandas cleaning/resampling exercise. Input is synthetic daily bars, not H1 market data."""
from pathlib import Path
import json
import pandas as pd

ROOT = Path(__file__).resolve().parent

def run():
    raw = pd.read_csv(ROOT / "ohlcv-dirty.csv")
    raw["timestamp"] = pd.to_datetime(raw["timestamp"], utc=True, errors="coerce")
    columns = ["open", "high", "low", "close", "volume"]
    raw[columns] = raw[columns].apply(pd.to_numeric, errors="coerce")
    valid = raw["timestamp"].notna() & raw[columns].notna().all(axis=1)
    valid &= raw[columns].map(lambda x: pd.notna(x) and abs(x) != float("inf")).all(axis=1)
    valid &= (raw[["open", "high", "low", "close"]] > 0).all(axis=1)
    valid &= raw["high"].ge(raw[["open", "close"]].max(axis=1))
    valid &= raw["low"].le(raw[["open", "close"]].min(axis=1)) & raw["volume"].ge(0)
    rejected = int((~valid).sum())
    clean = raw.loc[valid].sort_values("timestamp", kind="stable")
    duplicates = int(clean.duplicated("timestamp").sum())
    clean = clean.drop_duplicates("timestamp", keep="first").set_index("timestamp")
    assert clean.index.is_monotonic_increasing and clean.index.is_unique
    assert (len(clean), duplicates, rejected) == (240, 1, 3)
    clean["return"] = clean["close"].pct_change(fill_method=None)
    clean["sma_3"] = clean["close"].rolling(3, min_periods=3).mean()
    # Complete weekly OHLC aggregation, not an average of OHLC columns.
    weekly = clean.resample("W-FRI").agg({"open":"first", "high":"max", "low":"min", "close":"last", "volume":"sum"})
    example = pd.Series([100.,102.,101.])
    assert abs(example.pct_change(fill_method=None).iloc[-1] + 1/102) < 1e-12
    out = Path("pandas-results"); out.mkdir(exist_ok=True)
    clean.to_csv(out / "clean-features.csv")
    weekly.to_csv(out / "weekly-ohlcv.csv")
    report = {"kind":"synthetic", "valid":len(clean), "duplicates":duplicates, "rejected":rejected,
              "first_return_is_missing":bool(pd.isna(clean["return"].iloc[0])),
              "first_two_sma_are_missing":bool(clean["sma_3"].iloc[:2].isna().all()),
              "weekly_rows":len(weekly), "last_close":float(clean["close"].iloc[-1])}
    (out / "quality.json").write_text(json.dumps(report, indent=2),encoding="utf-8")
    print(json.dumps(report))
    return report

if __name__ == "__main__": run()
