from __future__ import annotations

from datetime import datetime, timedelta, timezone

import polars as pl

from uforia.storage import DatasetName, DatasetStore


def seed_options_context(store: DatasetStore, *, include_microstructure: bool = True) -> None:
    base = datetime(2026, 3, 1, 0, tzinfo=timezone.utc)
    option_rows: list[dict[str, object]] = []
    surface_rows: list[dict[str, object]] = []
    vvix_rows: list[dict[str, object]] = []
    razor_rows: list[dict[str, object]] = []
    funding_rows: list[dict[str, object]] = []
    perps_signal_rows: list[dict[str, object]] = []
    perps_composite_rows: list[dict[str, object]] = []
    microstructure_rows: list[dict[str, object]] = []
    microstructure_output_rows: list[dict[str, object]] = []

    for underlying, spot_base in (("BTC", 70000.0), ("ETH", 3500.0)):
        for hour in range(72):
            ts = base + timedelta(hours=hour)
            spot = spot_base + hour * (25.0 if underlying == "BTC" else 1.5)
            for days, base_iv in ((7, 0.55), (30, 0.60)):
                expiry = ts + timedelta(days=days)
                for strike_mult in (0.8, 0.9, 1.0, 1.1, 1.2):
                    strike = spot * strike_mult
                    call_mid = (
                        max((spot - strike) / spot, 0.0)
                        + base_iv * 0.05
                        + abs(strike_mult - 1) * 0.01
                    )
                    put_mid = (
                        max((strike - spot) / spot, 0.0)
                        + base_iv * 0.05
                        + abs(strike_mult - 1) * 0.01
                    )
                    mark_iv = base_iv + (strike_mult - 1.0) * 0.03
                    for option_type, mid in (("call", call_mid), ("put", put_mid)):
                        option_rows.append(
                            {
                                "ts": ts,
                                "date": ts.date(),
                                "venue": "deribit",
                                "underlying": underlying,
                                "expiry": expiry,
                                "instrument_name": (
                                    f"{underlying}-{hour}-{days}-{strike_mult}-{option_type}"
                                ),
                                "option_type": option_type,
                                "strike": strike,
                                "bid": max(mid - 0.001, 0.0001),
                                "ask": mid + 0.001,
                                "mark": mid,
                                "mid": mid,
                                "mark_iv": mark_iv,
                                "delta": 0.5 if option_type == "call" else -0.5,
                                "gamma": 0.02 * strike_mult,
                                "vega": 0.1,
                                "index_price": spot,
                                "underlying_price": spot,
                                "forward": spot,
                                "interest_rate": 0.0,
                                "open_interest": 100.0 * strike_mult,
                                "volume": 10.0 * strike_mult,
                                "quote_age_ms": 100,
                                "quality_flag": "ok",
                            }
                        )
            surface_rows.append(
                {
                    "ts": ts,
                    "date": ts.date(),
                    "underlying": underlying,
                    "source": "ssvi",
                    "atm_iv_7d": 0.50 + hour * 0.001,
                    "atm_iv_14d": 0.52 + hour * 0.001,
                    "atm_iv_30d": 0.56 + hour * 0.001,
                    "atm_iv_60d": 0.59 + hour * 0.001,
                    "rr_25_7d": -0.05 - hour * 0.0002,
                    "rr_25_30d": -0.03 - hour * 0.0001,
                    "bf_25_7d": 0.02,
                    "bf_25_30d": 0.03,
                    "term_slope_7_30": -0.06,
                    "term_slope_30_60": -0.03,
                    "fit_quality": 0.001,
                    "coverage_ratio": 0.8,
                    "maturity_violations": 0,
                    "fit_validity_flag": "ok",
                    "quality_flag": "ok",
                }
            )
            vvix_rows.append(
                {
                    "ts": ts,
                    "date": ts.date(),
                    "underlying": underlying,
                    "source": "dvol",
                    "vol_index_value": 55.0 + hour * 0.1,
                    "rvvix_7d": 90.0,
                    "rvvix_14d": 80.0 + hour * 0.05,
                    "rvvix_30d": 70.0,
                    "qvvix_30d": None,
                    "model_version": "rvvix-v1",
                    "quality_flag": "ok",
                }
            )
            razor_rows.append(
                {
                    "ts": ts,
                    "date": ts.date(),
                    "underlying": underlying,
                    "source": "synthetic_7d_atm",
                    "reference_tenor_days": 7,
                    "razor_pnl": float(hour),
                    "razor_vrp": float(hour) / 10.0,
                    "buyer_increment": 0.1,
                    "seller_increment": -0.1,
                    "option_reval_pnl": 0.05,
                    "hedge_pnl": 0.03,
                    "roll_pnl": 0.02,
                    "razor_pnl_zscore": 0.5,
                    "razor_vrp_zscore": 0.25,
                    "trade_band": "neutral",
                    "long_vol_signal": False,
                    "short_vol_signal": False,
                    "quality_flag": "ok",
                }
            )
            funding_rows.append(
                {
                    "ts": ts,
                    "date": ts.date(),
                    "venue": "deribit",
                    "underlying": underlying,
                    "source": "deribit_perpetual",
                    "interest_1h": 0.0001 + hour * 0.000001,
                    "interest_8h": 0.0008 + hour * 0.000005,
                    "quality_flag": "ok",
                }
            )
            perps_signal_rows.append(
                {
                    "ts": ts,
                    "date": ts.date(),
                    "asset": underlying,
                    "venue_scope": "all",
                    "source": "perps_family_v1",
                    "basis_bps": 15.0 if underlying == "BTC" else 9.0,
                    "funding_rate_1h": 0.0001,
                    "carry_annualized_pct": 12.0,
                    "carry_zscore_7d": 1.1,
                    "carry_zscore_30d": 0.9,
                    "carry_momentum_1h": 0.2,
                    "carry_momentum_24h": 0.4,
                    "cross_venue_funding_spread": 0.03,
                    "long_liq_notional": 50_000.0,
                    "short_liq_notional": 30_000.0,
                    "liq_asymmetry": 0.25,
                    "crowding_score": 0.6,
                    "cascade_risk_score": 0.4,
                    "liq_intensity_zscore": 0.2,
                    "oi_concentration": 0.35,
                    "cascade_regime": "stable",
                    "vpin_50": 0.5,
                    "toxic_flow_zscore_4h": 0.4,
                    "toxic_flow_zscore_24h": 0.35,
                    "ofi_persistence": 0.2,
                    "large_trade_ratio": 0.2,
                    "toxicity_regime": "normal",
                    "oi_change_1h": 0.3,
                    "oi_change_4h": 0.5,
                    "oi_change_24h": 1.2,
                    "price_change_1h": 15.0,
                    "oi_price_divergence": 0.1,
                    "oi_acceleration": 0.05,
                    "leverage_regime": "neutral",
                    "lead_lag_score": 0.2,
                    "venue_dislocation_bps": 1.0,
                    "convergence_half_life_secs": 120.0,
                    "price_discovery_leader": "binance",
                    "depth_recovery_speed": 0.8,
                    "spread_bps": 0.7,
                    "spread_zscore_4h": 0.1,
                    "spread_zscore_24h": 0.15,
                    "depth_imbalance_momentum": 0.05,
                    "spread_regime": "normal",
                    "rv_5s": 0.6,
                    "rv_1m": 0.4,
                    "rv_5m": 0.25,
                    "vol_signature_ratio": 1.2,
                    "vol_clustering": 0.3,
                    "rv_regime": "calm",
                    "cum_delta_acceleration": 0.1,
                    "delta_divergence": 0.05,
                    "absorption_ratio": 1.5,
                    "delta_regime": "balanced",
                    "quality_flag": "ok",
                }
            )
            perps_composite_rows.append(
                {
                    "ts": ts,
                    "date": ts.date(),
                    "asset": underlying,
                    "venue_scope": "all",
                    "source": "perps_composite_v1",
                    "carry_score": 0.7,
                    "cascade_risk_score": 0.4,
                    "toxicity_score": 0.8 if hour % 6 else 1.2,
                    "positioning_score": 0.3,
                    "fragility_score": 0.2,
                    "quality_flag": "ok",
                }
            )
            if include_microstructure:
                if underlying == "BTC":
                    route_venues = (
                        ("binance_spot", "spot", False, "spot", 1.0000, 2.0),
                        ("binance_futures", "futures", True, "linear_future", 1.0008, 2.5),
                        ("bybit_perps", "perp", True, "linear_perp", 1.0025, 4.5),
                    )
                else:
                    route_venues = (
                        ("binance_spot", "spot", False, "spot", 1.0000, 1.0),
                        ("binance_futures", "futures", True, "linear_future", 1.0040, 5.0),
                        ("bybit_perps", "perp", True, "linear_perp", 1.0010, 1.5),
                    )
                for venue, market_type, is_derivatives, contract_type, mult, spread in route_venues:
                    close = spot * mult
                    microstructure_rows.append(
                        {
                            "ts": ts,
                            "date": ts.date(),
                            "asset": underlying,
                            "venue": venue,
                            "exchange_symbol": venue,
                            "venue_group": "binance" if "binance" in venue else "bybit",
                            "market_type": market_type,
                            "is_derivatives": is_derivatives,
                            "contract_type": contract_type,
                            "clock": "event_time",
                            "bar_size_secs": 60,
                            "open": close - 1.0,
                            "high": close + 1.5,
                            "low": close - 1.5,
                            "close": close,
                            "volume": 100.0,
                            "buy_volume": 55.0,
                            "sell_volume": 45.0,
                            "trade_count": 12,
                            "vwap": close,
                            "microprice": close + 0.1,
                            "spread": spread,
                            "depth_bid_5": 500_000.0,
                            "depth_ask_5": 495_000.0,
                            "depth_notional_bid_5": 500_000.0 * close,
                            "depth_notional_ask_5": 495_000.0 * close,
                            "is_gap": False,
                            "quality_flag": "ok",
                        }
                    )
                for horizon, shift in (("30s", 0.02), ("1m", 0.04), ("2m", 0.06), ("5m", 0.08)):
                    microstructure_output_rows.append(
                        {
                            "ts": ts,
                            "date": ts.date(),
                            "asset": underlying,
                            "horizon": horizon,
                            "source": "tcn_boost_fusion",
                            "prob_down": 0.24 + shift / 4.0,
                            "prob_flat": 0.42,
                            "prob_up": 0.34 - shift / 4.0,
                            "expected_move_bps": 8.0 + hour * 0.05 + shift * 10.0,
                            "expected_edge_bps": 2.0 + shift * 5.0,
                            "tradability_score": 0.55 + shift,
                            "confidence": 0.62 + shift / 2.0,
                            "confidence_bucket": "medium",
                            "regime_state": "trend_up" if hour % 5 else "neutral",
                            "blocked_reason": None,
                            "model_version": "tcn_boost_fusion_v2",
                            "model_family": "tcn_boost_fusion",
                            "quality_flag": "ok",
                        }
                    )

    store.write(DatasetName.OPTION_CHAIN_SNAPSHOT, pl.DataFrame(option_rows))
    store.write(DatasetName.SURFACE_FEATURES, pl.DataFrame(surface_rows))
    store.write(DatasetName.VVIX_SERIES, pl.DataFrame(vvix_rows))
    store.write(DatasetName.RAZOR_SERIES, pl.DataFrame(razor_rows))
    store.write(DatasetName.FUNDING_RATE_SNAPSHOT, pl.DataFrame(funding_rows))
    store.write(DatasetName.PERPS_SIGNAL_SERIES, pl.DataFrame(perps_signal_rows))
    store.write(DatasetName.PERPS_COMPOSITE_SERIES, pl.DataFrame(perps_composite_rows))
    if microstructure_rows:
        store.write(DatasetName.MICROSTRUCTURE_BAR, pl.DataFrame(microstructure_rows))
    if microstructure_output_rows:
        store.write(
            DatasetName.MICROSTRUCTURE_MODEL_OUTPUT, pl.DataFrame(microstructure_output_rows)
        )
