"""Slippage Mitigation - estimates and minimizes execution slippage.

Calculates expected slippage based on volume, volatility and order size.
"""
from __future__ import annotations
from app.engine.base import BaseAlgorithm
from app.engine.context import AlgorithmContext


class SlippageAlgorithm(BaseAlgorithm):
    algorithm_id = 'behavioral.slippage'
    version = '1.0.0'
    category = 'behavioral'
    display_name = 'Slippage Estimator'
    dependencies = ['technical.atr']

    def compute(self, ctx: AlgorithmContext) -> AlgorithmContext:
        price = ctx.current_price
        if not price:
            return ctx

        df = ctx.ohlcv
        if df is None or len(df) < 5:
            return ctx

        atr = ctx.indicators.get('atr_latest', 0)
        atr_pct = (atr / price * 100) if price > 0 else 0

        # Average spread estimate from high-low of recent candles
        recent = df.tail(10)
        avg_spread_pct = ((recent['high'] - recent['low']) / recent['close']).mean() * 100

        # Volume analysis
        avg_vol = df['volume'].tail(20).mean()
        last_vol = float(df['volume'].iloc[-1])
        vol_ratio = last_vol / avg_vol if avg_vol > 0 else 1

        # Order size relative to volume
        active_capital = ctx.capital_idr * (ctx.active_pct / 100)
        order_value = active_capital * 0.25
        order_qty = order_value / price if price > 0 else 0
        order_vol_pct = (order_qty / avg_vol * 100) if avg_vol > 0 else 0

        # Estimated slippage components
        volatility_slip = atr_pct * 0.1   # 10% of ATR as volatility cost
        impact_slip = order_vol_pct * 0.5  # market impact
        spread_slip = avg_spread_pct * 0.5  # half the spread

        total_slip_pct = volatility_slip + impact_slip + spread_slip
        total_slip_idr = order_value * (total_slip_pct / 100)

        # Recommendation
        if total_slip_pct < 0.1:
            recommendation = 'SAFE'
            advice = 'Low slippage expected, market order acceptable'
        elif total_slip_pct < 0.3:
            recommendation = 'CAUTION'
            advice = 'Use limit orders to minimize slippage'
        elif total_slip_pct < 1.0:
            recommendation = 'SPLIT'
            advice = 'Split order into smaller tranches (use Ghost Mode)'
        else:
            recommendation = 'AVOID'
            advice = 'High slippage risk, consider waiting for better liquidity'

        ctx.quantitative['slippage'] = {
            'estimated_slippage_pct': round(total_slip_pct, 4),
            'estimated_slippage_idr': round(total_slip_idr, 0),
            'components': {
                'volatility': round(volatility_slip, 4),
                'market_impact': round(impact_slip, 4),
                'spread': round(spread_slip, 4),
            },
            'avg_spread_pct': round(avg_spread_pct, 4),
            'volume_ratio': round(vol_ratio, 2),
            'order_vol_impact_pct': round(order_vol_pct, 4),
            'recommendation': recommendation,
            'advice': advice,
        }
        return ctx
