from __future__ import annotations

from datetime import datetime, timedelta, timezone

import polars as pl
import pytest

from uforia.analytics.vol_index import _compute_bvix, _interpolate_constant_maturity_variance


def test_compute_bvix_from_synthetic_snapshot() -> None:
    ts = datetime(2026, 3, 1, 0, tzinfo=timezone.utc)
    rows = []
    for days, base_iv in ((20, 0.55), (40, 0.60)):
        expiry = ts + timedelta(days=days)
        for strike, call_mid, put_mid in (
            (90000.0, 0.0025, 0.0002),
            (95000.0, 0.0018, 0.0005),
            (100000.0, 0.0012, 0.0012),
            (105000.0, 0.0007, 0.0019),
            (110000.0, 0.0003, 0.0027),
        ):
            for option_type, mid in (("call", call_mid), ("put", put_mid)):
                rows.append(
                    {
                        "ts": ts,
                        "date": ts.date(),
                        "venue": "deribit",
                        "underlying": "BTC",
                        "expiry": expiry,
                        "instrument_name": f"BTC-{days}-{strike}-{option_type}",
                        "option_type": option_type,
                        "strike": strike,
                        "bid": mid,
                        "ask": mid,
                        "mark": mid,
                        "mid": mid,
                        "mark_iv": base_iv,
                        "delta": 0.1,
                        "vega": 0.1,
                        "index_price": 100000.0,
                        "underlying_price": 100000.0,
                        "forward": 100000.0,
                        "interest_rate": 0.0,
                        "open_interest": 1.0,
                        "volume": 1.0,
                        "quote_age_ms": 1000,
                        "quality_flag": "ok",
                    }
                )
    snapshot = pl.DataFrame(rows)
    value = _compute_bvix(snapshot)
    assert value > 0
    assert value < 300


def test_constant_maturity_variance_interpolation_scales_to_target_tenor() -> None:
    near_var = 0.40
    next_var = 0.34
    near_t = 20 / 365.0
    next_t = 40 / 365.0
    target_t = 30 / 365.0

    interpolated = _interpolate_constant_maturity_variance(
        near_var,
        next_var,
        near_t,
        next_t,
        target_t,
    )

    assert interpolated == pytest.approx(0.36)
