"""Risk management helpers."""

from __future__ import annotations

from typing import Optional


def position_size_by_risk(
    account_balance: float,
    risk_percent: float,
    entry_price: float,
    stop_loss_price: float,
    pip_value: float = 10.0,
    *,
    symbol: str = "",
) -> float:
    """Calculate position size in lots based on account risk.

    Uses the fixed-fractional method::

        risk_amount = account_balance * (risk_percent / 100)
        pips_risked = |entry - stop_loss| / pip_size
        lots = risk_amount / (pips_risked * pip_value)

    Parameters
    ----------
    account_balance : float
        Account equity or balance in account currency.
    risk_percent : float
        Percentage of account to risk per trade (e.g. 1.0 for 1%).
    entry_price : float
        Planned entry price.
    stop_loss_price : float
        Stop-loss price.
    pip_value : float
        Pip monetary value per full lot (default: 10 USD for most forex pairs).
        Adjust for the specific instrument.
    symbol : str, optional
        Symbol name (for logging).

    Returns
    -------
    float
        Position size in lots, capped at a reasonable minimum (0.01 lots).
    """
    if entry_price == stop_loss_price:
        return 0.01
    risk_amount = account_balance * (risk_percent / 100.0)
    if risk_amount <= 0:
        return 0.01

    price_diff = abs(entry_price - stop_loss_price)
    # Derive pip size from price difference (crude approximation)
    # For forex: 0.0001 per pip, for JPY: 0.01 per pip
    pip_size = 0.0001 if not symbol.endswith("JPY") else 0.01
    pips_risked = price_diff / pip_size
    if pips_risked <= 0:
        return 0.01

    lots = risk_amount / (pips_risked * pip_value)
    return max(0.01, round(lots, 2))


def simple_stop_tp(
    entry_price: float,
    side: str,
    atr: float = 0.0,
    atr_multiplier: float = 2.0,
    risk_reward: float = 2.0,
) -> tuple[float, float]:
    """Calculate simple stop-loss and take-profit from entry price.

    If ``atr`` is provided, SL/TP are set using ATR multiples.
    Otherwise, a fixed risk-reward ratio is used.

    Parameters
    ----------
    entry_price : float
    side : str
        "BUY" or "SELL".
    atr : float
        Average True Range in price units (optional).
    atr_multiplier : float
        Multiplier for ATR to set stop loss distance.
    risk_reward : float
        Ratio of TP distance to SL distance (used when atr == 0).

    Returns
    -------
    tuple[float, float]
        (stop_loss_price, take_profit_price)
    """
    side = side.upper()
    if atr > 0:
        sl_distance = atr * atr_multiplier
        tp_distance = sl_distance * risk_reward
    else:
        # Use a sensible default: 0.5% for stop, 1% for TP
        sl_distance = entry_price * 0.005
        tp_distance = entry_price * 0.01

    if side == "BUY":
        sl = entry_price - sl_distance
        tp = entry_price + tp_distance
    else:
        sl = entry_price + sl_distance
        tp = entry_price - tp_distance

    return round(sl, 5), round(tp, 5)
