from dataclasses import dataclass
from typing import List, Dict


@dataclass(frozen=True)
class BloombergSchema:
    name: str
    required_columns: List[str]
    optional_columns: List[str] | None = None
    description: str | None = None

# Underlying price data
OHLCV_SCHEMA = BloombergSchema(
    name="ohlcv.csv",
    required_columns=[
        "Date",
        "Open",
        "High",
        "Low",
        "Close",
        "Volume",
    ],
    description="Underlying OHLCV daily prices",
)

# Option chain snapshot
CHAIN_SCHEMA = BloombergSchema(
    name="chain.csv",
    required_columns=[
        "Call Ticker",
        "Put Ticker",
        "Expiration",
        "Strike",
        "Series",
        "Exercise Type",
        "Contract Size",
        "Periodicity",
    ],
    optional_columns=[
        "Adjusted",
        "Version Number",
        "Generation Number",
    ],
    description="Single snapshot of option chain metadata",
)

# Implied volatility (moneyness smiles)
IVOL_30_MNY_SCHEMA = BloombergSchema(
    name="ivol_30_mny.csv",
    required_columns=[
        "Date",
        "IVOL_30_90",
        "IVOL_30_95",
        "IVOL_30_100",
        "IVOL_30_105",
        "IVOL_30_110",
    ],
    description="30D implied volatility smile by moneyness",
)

IVOL_60_MNY_SCHEMA = BloombergSchema(
    name="ivol_60_mny.csv",
    required_columns=[
        "Date",
        "IVOL_60_90",
        "IVOL_60_95",
        "IVOL_60_100",
        "IVOL_60_105",
        "IVOL_60_110",
    ],
    description="60D implied volatility smile by moneyness",
)

# Delta-based IV surface snapshot
IV_SURFACE_SCHEMA = BloombergSchema(
    name="ivol_surface.csv",
    required_columns=[
        "Expiration",
        "Delta Level",
        "Strike",
        "Implied Volatility",
        "Underlying Price",
        "Dividend",
    ],
    description="Single-date IV surface across delta levels",
)

# Open interest & ATM IV
OI_SCHEMA = BloombergSchema(
    name="oi.csv",
    required_columns=[
        "Date",
        "Close",
        "Bid",
        "Ask",
        "Total Call Open Interest",
        "Total Put Open Interest",
        "Volume",
        "Historical Call Implied Volatility",
        "Historical Put Implied Volatility",
    ],
    description="Aggregate open interest, volume, and historical ATM IV",
)

# Rates & volatility index
SOFR_SCHEMA = BloombergSchema(
    name="riskfree_sofr.csv",
    required_columns=[
        "Date",
        "Risk Free SOFR",
    ],
    description="SOFR 90D risk-free rate (percent)",
)

USGG_SCHEMA = BloombergSchema(
    name="riskfree_usgg.csv",
    required_columns=[
        "Date",
        "Risk Free USGG",
    ],
    description="US Treasury 3M yield (percent)",
)

VIX_SCHEMA = BloombergSchema(
    name="vix.csv",
    required_columns=[
        "Date",
        "Close",
    ],
    description="VIX index level",
)

# Registry (used by validators)
BLOOMBERG_SCHEMAS: Dict[str, BloombergSchema] = {
    "ohlcv": OHLCV_SCHEMA,
    "chain": CHAIN_SCHEMA,
    "ivol_30_mny": IVOL_30_MNY_SCHEMA,
    "ivol_60_mny": IVOL_60_MNY_SCHEMA,
    "ivol_surface": IV_SURFACE_SCHEMA,
    "oi": OI_SCHEMA,
    "riskfree_sofr": SOFR_SCHEMA,
    "riskfree_usgg": USGG_SCHEMA,
    "vix": VIX_SCHEMA,
}
