from fastapi import APIRouter, Query
from typing import Optional
from services.options_pricer import (
    black_scholes, compute_pnl_curve, bull_call_spread,
    bear_put_spread, long_straddle, implied_vol_surface
)
from services.data_fetcher import get_quote, compute_historical_iv

router = APIRouter(prefix="/api/options", tags=["options"])


@router.get("/price")
def price_option(
    symbol: str = Query(...),
    strike: float = Query(...),
    expiry_days: int = Query(90),
    option_type: str = Query("call"),
    rate: float = Query(0.05),
):
    q = get_quote(symbol)
    S = q["price"] if q and "price" in q else strike
    sigma = compute_historical_iv(symbol)
    T = expiry_days / 365
    result = black_scholes(S, strike, T, rate, sigma, option_type)
    result["underlying_price"] = S
    result["sigma"] = sigma
    return result


@router.get("/pnl-curve")
def pnl_curve(
    symbol: str = Query(...),
    strike: float = Query(...),
    expiry_days: int = Query(90),
    option_type: str = Query("call"),
    quantity: int = Query(1),
    premium_paid: float = Query(...),
    rate: float = Query(0.05),
):
    q = get_quote(symbol)
    S = q["price"] if q and "price" in q else strike
    sigma = compute_historical_iv(symbol)
    T = expiry_days / 365
    return compute_pnl_curve(S, strike, T, rate, sigma, option_type, quantity, premium_paid)


@router.get("/strategy/bull-call-spread")
def bull_spread(
    symbol: str = Query(...),
    strike_low: float = Query(...),
    strike_high: float = Query(...),
    expiry_days: int = Query(90),
    rate: float = Query(0.05),
):
    q = get_quote(symbol)
    S = q["price"] if q and "price" in q else strike_low
    sigma = compute_historical_iv(symbol)
    T = expiry_days / 365
    result = bull_call_spread(S, strike_low, strike_high, T, rate, sigma)
    result["underlying_price"] = S
    result["sigma"] = sigma
    return result


@router.get("/strategy/bear-put-spread")
def bear_spread(
    symbol: str = Query(...),
    strike_high: float = Query(...),
    strike_low: float = Query(...),
    expiry_days: int = Query(90),
    rate: float = Query(0.05),
):
    q = get_quote(symbol)
    S = q["price"] if q and "price" in q else strike_high
    sigma = compute_historical_iv(symbol)
    T = expiry_days / 365
    result = bear_put_spread(S, strike_high, strike_low, T, rate, sigma)
    result["underlying_price"] = S
    result["sigma"] = sigma
    return result


@router.get("/strategy/straddle")
def straddle(
    symbol: str = Query(...),
    strike: float = Query(...),
    expiry_days: int = Query(90),
    rate: float = Query(0.05),
):
    q = get_quote(symbol)
    S = q["price"] if q and "price" in q else strike
    sigma = compute_historical_iv(symbol)
    T = expiry_days / 365
    result = long_straddle(S, strike, T, rate, sigma)
    result["underlying_price"] = S
    result["sigma"] = sigma
    return result


@router.get("/iv-surface")
def iv_surface(
    symbol: str = Query(...),
    rate: float = Query(0.05),
):
    q = get_quote(symbol)
    S = q["price"] if q and "price" in q else 100.0
    sigma = compute_historical_iv(symbol)
    strikes_pct = [0.80, 0.85, 0.90, 0.95, 1.00, 1.05, 1.10, 1.15, 1.20]
    expiries = [7, 14, 30, 60, 90, 180]
    surface = implied_vol_surface(S, strikes_pct, expiries, rate, sigma)
    return {"symbol": symbol, "spot": S, "surface": surface}
