import polars as pl

# Enhanced OHLCV Schema
enhanced_ohlcv_schema = {
    "idx": pl.Int64,
    "ts": pl.Datetime("ms"),
    "open": pl.Float64,
    "high": pl.Float64,
    "low": pl.Float64,
    "close": pl.Float64,
    "volume": pl.Float64,
    "gap_type": pl.Int64,
    "gap_points": pl.Float64,
    "gap_range_min": pl.Float64,
    "gap_range_max": pl.Float64,
    "entry_signal": pl.Boolean,
    "exit_signal": pl.Boolean,
    "cleaned_entry_signal": pl.Boolean,
    "cleaned_exit_signal": pl.Boolean,
    "base_entry_price": pl.Float64,
    "base_entry_strategy": pl.Int64,
    "base_exit_price": pl.Float64,
    "base_exit_strategy": pl.Int64,
    "base_position_id": pl.Int64,
    # 巢狀結構統一使用 Struct
    "base_trading_context": pl.Struct(
        [
            pl.Field("bars_in_position", pl.Int64),
            pl.Field("highest_since_entry", pl.Float64),
            pl.Field("lowest_since_entry", pl.Float64),
            pl.Field("position_entry_price", pl.Float64),
        ]
    ),
    # 來自 trigger 自動產生
    # "base_entry": pl.Struct(
    #     [
    #         pl.Field("cond", pl.Boolean),
    #         pl.Field("price", pl.Float64),
    #         pl.Field("strategy", pl.Int64),
    #         pl.Field("priority", pl.Int64),
    #     ]
    # ),
    "advanced_favorable_entry_hypo_price": pl.Float64,
    "advanced_adverse_entry_hypo_price": pl.Float64,
    "advanced_neutral_entry_hypo_price": pl.Float64,
    "advanced_favorable_entry_strategy": pl.Int64,
    "advanced_adverse_entry_strategy": pl.Int64,
    "advanced_neutral_entry_strategy": pl.Int64,
    "advanced_entry_price": pl.Float64,
    "advanced_entry_strategy": pl.Int64,
    "is_entry_gap_filled": pl.Boolean,
    "advanced_cleaned_entry_signal": pl.Boolean,
    "advanced_entry_position_id": pl.Int64,
    "advanced_entry_trading_context": pl.Struct(
        [
            pl.Field("bars_since_advanced_entry", pl.Int64),
            pl.Field("highest_since_advanced_entry", pl.Float64),
            pl.Field("lowest_since_advanced_entry", pl.Float64),
            pl.Field("position_entry_price", pl.Float64),
        ]
    ),
    # 來自 trigger 自動產生
    # "base_exit": pl.Struct(
    #     [
    #         pl.Field("cond", pl.Boolean),
    #         pl.Field("price", pl.Float64),
    #         pl.Field("strategy", pl.Int64),
    #         pl.Field("priority", pl.Int64),
    #     ]
    # ),
    "advanced_favorable_exit_hypo_price": pl.Float64,
    "advanced_adverse_exit_hypo_price": pl.Float64,
    "advanced_neutral_exit_hypo_price": pl.Float64,
    "advanced_favorable_exit_strategy": pl.Int64,
    "advanced_adverse_exit_strategy": pl.Int64,
    "advanced_neutral_exit_strategy": pl.Int64,
    "advanced_exit_price": pl.Float64,
    "advanced_exit_strategy": pl.Int64,
    "is_exit_gap_filled": pl.Boolean,
    "advanced_cleaned_exit_signal": pl.Boolean,
    "advanced_exit_position_id": pl.Int64,
    "advanced_exit_trading_context": pl.Struct(
        [
            pl.Field("bars_since_advanced_entry", pl.Int64),
            pl.Field("highest_since_advanced_entry", pl.Float64),
            pl.Field("lowest_since_advanced_entry", pl.Float64),
            pl.Field("position_entry_price", pl.Float64),
        ]
    ),
    "is_entry_valid": pl.Boolean,
    "entry_rejection_reason": pl.Utf8,
    "validated_entry_signal": pl.Boolean,
    "validated_exit_signal": pl.Boolean,
    "final_position_id": pl.Int64,
    "final_trading_context": pl.Struct(
        [
            pl.Field("bars_in_position", pl.Int64),
            pl.Field("highest_since_entry", pl.Float64),
            pl.Field("lowest_since_entry", pl.Float64),
            pl.Field("position_entry_price", pl.Float64),
        ]
    ),
    "strategy_name": pl.Utf8,
    "blueprint_name": pl.Utf8,
}

# Trades Schema (from backtest-results or latest-trades export)
# Complete schema matching API response with MAE/MFE fields
trades_schema = {
    # Position identifiers
    "final_position_id": pl.UInt32,
    "position_id": pl.UInt32,
    "direction": pl.Int32,  # -1 for Short, 1 for Long
    "status": pl.Boolean,  # false = closed, true = open

    # Entry details
    "entry_idx": pl.UInt32,
    "entry_time": pl.Datetime("ms"),
    "entry_price": pl.Float64,
    "entry_reason": pl.UInt32,
    "favorable_entry_hypo_price": pl.Float64,
    "adverse_entry_hypo_price": pl.Float64,
    "favorable_entry_strategy": pl.UInt32,
    "adverse_entry_strategy": pl.UInt32,

    # Exit details
    "exit_idx": pl.UInt32,
    "exit_time": pl.Datetime("ms"),
    "exit_price": pl.Float64,
    "exit_reason": pl.UInt32,
    "favorable_exit_hypo_price": pl.Float64,
    "adverse_exit_hypo_price": pl.Float64,
    "favorable_exit_strategy": pl.UInt32,
    "adverse_exit_strategy": pl.UInt32,

    # Holding period
    "holding_seconds": pl.Int64,
    "holding_bars": pl.UInt32,

    # MAE/MFE metrics (Maximum Adverse/Favorable Excursion)
    "g_mfe": pl.Float64,      # Global Maximum Favorable Excursion
    "mae": pl.Float64,        # Maximum Adverse Excursion
    "mfe": pl.Float64,        # Maximum Favorable Excursion
    "mae_lv1": pl.Float64,    # MAE Level 1
    "mhl": pl.Float64,        # Maximum High/Low

    # MAE/MFE indices (bar index where each occurred)
    "g_mfe_idx": pl.UInt32,
    "mae_idx": pl.UInt32,
    "mfe_idx": pl.UInt32,
    "mae_lv1_idx": pl.UInt32,
    "mhl_idx": pl.UInt32,

    # Volatility at each key point (typically ATR)
    "entry_volatility": pl.Float64,
    "exit_volatility": pl.Float64,
    "g_mfe_volatility": pl.Float64,
    "mae_volatility": pl.Float64,
    "mfe_volatility": pl.Float64,
    "mae_lv1_volatility": pl.Float64,
    "mhl_volatility": pl.Float64,

    # P&L metrics
    "pnl": pl.Float64,        # Absolute profit/loss
    "pnl_pct": pl.Float64,    # Percentage profit/loss

    # Metadata
    "strategy_name": pl.Utf8,
    "blueprint_name": pl.Utf8,
}

# Performance Schema (from backtest-results export)
performance_schema = {
    "strategy_name": pl.Utf8,
    "total_trades": pl.Int64,
    "win_trades": pl.Int64,
    "loss_trades": pl.Int64,
    "win_rate": pl.Float64,
    "total_pnl": pl.Float64,
    "avg_pnl": pl.Float64,
    "max_drawdown": pl.Float64,
    "sharpe_ratio": pl.Float64,
    "sortino_ratio": pl.Float64,
    "max_consecutive_wins": pl.Int64,
    "max_consecutive_losses": pl.Int64,
}
