from qfinindia.volatility.rnd import RND
from qfinindia.volatility.distribution import Distribution
from qfinindia.volatility.tailrisk import TailRisk
from qfinindia.volatility.vol_metrics import VolMetrics
import pandas as pd


def _compute_metrics(chain, expiry):
    """
    Internal: compute all implied parameters once
    """
    rnd = RND.from_chain(chain, expiry)
    dist = Distribution.from_rnd(rnd)
    tail = TailRisk.from_distribution(dist)
    vm = VolMetrics(chain)

    spot = chain.underlying
    fwd = dist.mean()
    move = dist.std()

    metrics = {
        "spot": float(spot),
        "forward": float(fwd),
        "forward_pct": float((fwd - spot) / spot),
        "expected_move": float(move),
        "atm_vol": float(vm.atm_vol()),
        "skew": float(dist.skew()),
        "var_5": float(tail.var(0.05)),
        "var_1": float(tail.var(0.01)),
        "bias": "Bullish" if fwd > spot else "Bearish" if fwd < spot else "Neutral",
    }

    return metrics


def generate_report(chain, expiry, output="text"):
    """
    Generate QFinIndia implied market report.

    Parameters
    ----------
    chain : OptionChain
    expiry : str or datetime
    output : {"text","dict","df"}

    Returns
    -------
    str | dict | pandas.DataFrame
    """
    m = _compute_metrics(chain, expiry)

    if output == "dict":
        return m

    if output == "df":
        return pd.DataFrame([m])

    # default text
    report = f"""
QFinIndia IMPLIED MARKET REPORT
--------------------------------
Spot: {m['spot']:.0f}
Forward: {m['forward']:.0f} ({m['forward_pct']*100:.2f}%)

Expected Move: ±{m['expected_move']:.0f}
ATM Vol: {m['atm_vol']:.2f}
Skew: {m['skew']:.2f}

VaR 5%: {m['var_5']:.0f}
VaR 1%: {m['var_1']:.0f}

Bias: {m['bias']}
"""
    return report.strip()
