"""
Portfolio simulation utilities for backtesting.

Handles long-only and long/short portfolio creation using VectorBT.
"""
import pandas as pd
import vectorbt as vbt

from engine.logging_config import get_logger

logger = get_logger(__name__)


def run_long_only_portfolio(
    close: pd.Series,
    entries: pd.DataFrame,
    exits: pd.DataFrame,
    init_cash: float,
    fees: float,
    slippage: float,
    freq: str,
    sl_stop: float | None,
    tp_stop: float | None,
    sl_trail: bool,
    leverage: int
) -> vbt.Portfolio:
    """
    Run a long-only portfolio simulation.
    
    Args:
        close: Close price series
        entries: Entry signals
        exits: Exit signals
        init_cash: Initial capital
        fees: Transaction fee percentage
        slippage: Slippage percentage
        freq: Data frequency string
        sl_stop: Stop loss percentage
        tp_stop: Take profit percentage
        sl_trail: Enable trailing stop loss
        leverage: Leverage multiplier
        
    Returns:
        VectorBT Portfolio object
    """
    effective_cash = init_cash * leverage
    
    return vbt.Portfolio.from_signals(
        close=close,
        entries=entries,
        exits=exits,
        init_cash=effective_cash,
        fees=fees,
        slippage=slippage,
        freq=freq,
        sl_stop=sl_stop,
        tp_stop=tp_stop,
        sl_trail=sl_trail,
        size=1.0,
        size_type='percent',
    )


def run_long_short_portfolio(
    close: pd.Series,
    long_entries: pd.DataFrame,
    long_exits: pd.DataFrame,
    short_entries: pd.DataFrame,
    short_exits: pd.DataFrame,
    init_cash: float,
    fees: float,
    slippage: float,
    freq: str,
    sl_stop: float | None,
    tp_stop: float | None,
    sl_trail: bool,
    leverage: int,
    size: pd.Series | float = 1.0,
    size_type: str = 'value'  # Changed to 'value' to support reversals/sizing
) -> vbt.Portfolio:
    """
    Run a portfolio supporting both long and short positions.
    
    Uses VectorBT's native support for short_entries/short_exits
    to simulate a single unified portfolio.
    """
    effective_cash = init_cash * leverage
    
    # If size is passed as value (USD), we don't scale it by leverage here
    # The backtester has already scaled it by init_cash.
    # If using 'value', vbt treats it as "Amount of CASH to use for the trade"
    
    return vbt.Portfolio.from_signals(
        close=close,
        entries=long_entries,
        exits=long_exits,
        short_entries=short_entries,
        short_exits=short_exits,
        init_cash=effective_cash,
        fees=fees,
        slippage=slippage,
        freq=freq,
        sl_stop=sl_stop,
        tp_stop=tp_stop,
        sl_trail=sl_trail,
        size=size,
        size_type=size_type,
    )
