import pandas as pd

from .pandas import raise_if_not_datetime_index


def get_daily_vol(close: pd.Series, lookback: int = 100, dropna: bool = False) -> pd.Series:
    """
    Calculate daily volatility at each intraday timestamp.

    Uses exponentially weighted moving standard deviation of daily returns,
    where daily returns are computed relative to the same time on the previous day.

    Parameters
    ----------
    close : pd.Series
        Intraday closing prices with DatetimeIndex
    lookback : int, default 100
        Span for EWMA (alpha = 2 / (span + 1))

    Returns
    -------
    pd.Series
        Daily volatility estimates at each timestamp
    """
    raise_if_not_datetime_index(close.index)

    # Get the close price from 1 trading day ago
    prev_day_close = close.shift(1, freq=pd.Timedelta(days=1))
    # Cut off the last elements of prev_day_close that are beyond the max timestamp of close due to the shift
    prev_day_close = prev_day_close[prev_day_close.index <= close.index.max()]

    # Calculate daily returns (current close / previous day close - 1)
    daily_returns = close / prev_day_close - 1

    if dropna:
        # Remove NaN values where previous day data doesn't exist
        daily_returns = daily_returns.dropna()

    # Calculate exponentially weighted moving standard deviation
    daily_vol = daily_returns.ewm(span=lookback, min_periods=lookback).std()

    if dropna:
        # Drop initial NaN values where lookback period is not met
        daily_vol = daily_vol.dropna()

    return daily_vol
