"""Core data models for the autonomous trading engine.

Defines dataclasses for risk tier configuration, portfolio state,
trading decisions, position sizing results, stop levels, and
performance metrics used across all trading engine components.
"""

from __future__ import annotations

from dataclasses import dataclass, field
from datetime import datetime, timedelta, timezone

# ---------------------------------------------------------------------------
# Risk Tier Configuration
# ---------------------------------------------------------------------------


@dataclass
class RiskTierConfig:
    """Parameters for a named risk tier (conservative/moderate/aggressive)."""

    name: str
    min_confidence: float
    max_position_pct: float
    stop_loss_atr_multiplier: float
    reward_risk_ratio: float
    max_sector_pct: float
    max_portfolio_heat: float


RISK_TIER_DEFAULTS: dict[str, RiskTierConfig] = {
    "conservative": RiskTierConfig(
        name="conservative",
        min_confidence=0.75,
        max_position_pct=0.05,
        stop_loss_atr_multiplier=1.5,
        reward_risk_ratio=2.0,
        max_sector_pct=0.20,
        max_portfolio_heat=0.10,
    ),
    "moderate": RiskTierConfig(
        name="moderate",
        min_confidence=0.55,
        max_position_pct=0.10,
        stop_loss_atr_multiplier=2.0,
        reward_risk_ratio=1.5,
        max_sector_pct=0.30,
        max_portfolio_heat=0.20,
    ),
    "aggressive": RiskTierConfig(
        name="aggressive",
        min_confidence=0.40,
        max_position_pct=0.15,
        stop_loss_atr_multiplier=2.5,
        reward_risk_ratio=1.2,
        max_sector_pct=0.40,
        max_portfolio_heat=0.30,
    ),
}


# ---------------------------------------------------------------------------
# Portfolio State
# ---------------------------------------------------------------------------


@dataclass
class PortfolioState:
    """Snapshot of the current portfolio used for decision-making."""

    positions: list = field(default_factory=list)
    total_value: float = 0.0
    cash: float = 0.0
    active_pool: float = 0.0
    reserve_pool: float = 0.0
    sector_exposure: dict[str, float] = field(default_factory=dict)
    portfolio_heat: float = 0.0
    open_position_count: int = 0


# ---------------------------------------------------------------------------
# Trading Decision
# ---------------------------------------------------------------------------


@dataclass
class TradingDecision:
    """Record of a trading decision (act or skip), persisted for audit trail."""

    id: str
    recommendation_id: str | None
    decision: str
    skip_reason: str | None
    ticker: str
    computed_position_size: float | None
    computed_share_quantity: int | None
    risk_tier_at_decision: str
    portfolio_heat_at_decision: float | None
    active_pool_at_decision: float | None
    reserve_pool_at_decision: float | None
    circuit_breaker_status: str
    correlation_check_result: dict = field(default_factory=dict)
    sector_exposure_check_result: dict = field(default_factory=dict)
    earnings_proximity_flag: bool = False
    is_micro_trade: bool = False
    decision_trace: dict = field(default_factory=dict)
    created_at: datetime = field(default_factory=lambda: datetime.now(tz=timezone.utc))


# ---------------------------------------------------------------------------
# Position Sizing
# ---------------------------------------------------------------------------


@dataclass
class PositionSizeResult:
    """Output of the position sizer computation."""

    dollar_amount: float
    share_quantity: int
    allocation_pct: float
    adjustments: list[str] = field(default_factory=list)
    rejected: bool = False
    rejection_reason: str = ""


# ---------------------------------------------------------------------------
# Stop-Loss / Take-Profit Levels
# ---------------------------------------------------------------------------


@dataclass
class StopLevels:
    """Current stop-loss and take-profit levels for an open position."""

    stop_loss_price: float
    take_profit_price: float
    trailing_stop_active: bool
    atr_value: float
    atr_multiplier: float
    reward_risk_ratio: float
    last_updated: datetime = field(default_factory=lambda: datetime.now(tz=timezone.utc))


# ---------------------------------------------------------------------------
# Open / Closed Positions
# ---------------------------------------------------------------------------


@dataclass
class OpenPosition:
    """Representation of a currently held position."""

    ticker: str
    quantity: int
    entry_price: float
    current_price: float
    unrealized_pnl: float
    market_value: float
    sector: str
    stop_loss_price: float
    take_profit_price: float
    signal_confidence: float
    is_micro_trade: bool = False


@dataclass
class ClosedTrade:
    """Record of a completed (closed) trade."""

    ticker: str
    entry_price: float
    exit_price: float
    quantity: int
    pnl: float
    pnl_pct: float
    hold_duration: timedelta
    recommendation_id: str | None = None
    is_micro_trade: bool = False


# ---------------------------------------------------------------------------
# Performance Metrics
# ---------------------------------------------------------------------------


@dataclass
class PerformanceMetrics:
    """Portfolio-wide performance metrics computed periodically."""

    total_portfolio_value: float
    active_pool: float
    reserve_pool: float
    unrealized_pnl: float
    realized_pnl: float
    daily_pnl: float
    win_count: int
    loss_count: int
    win_rate: float
    avg_win: float
    avg_loss: float
    profit_factor: float
    sharpe_ratio: float
    max_drawdown: float
    current_drawdown_pct: float
    portfolio_heat: float
    computed_at: datetime = field(default_factory=lambda: datetime.now(tz=timezone.utc))


# ---------------------------------------------------------------------------
# Circuit Breaker
# ---------------------------------------------------------------------------


@dataclass
class CircuitBreakerState:
    """Current state of the circuit breaker safety mechanism."""

    active: bool = False
    trigger_type: str | None = None
    triggered_at: datetime | None = None
    cooldown_expires: datetime | None = None
    ticker_cooldowns: dict[str, datetime] = field(default_factory=dict)


# ---------------------------------------------------------------------------
# Reserve Pool
# ---------------------------------------------------------------------------


@dataclass
class ReservePoolState:
    """Current state of the reserve pool."""

    balance: float = 0.0
    total_deposits: float = 0.0
    total_withdrawals: float = 0.0
    last_updated: datetime = field(default_factory=lambda: datetime.now(tz=timezone.utc))


# ---------------------------------------------------------------------------
# Stop Trigger
# ---------------------------------------------------------------------------


@dataclass
class StopTrigger:
    """A triggered stop-loss or take-profit event for a position."""

    ticker: str
    trigger_type: str  # "stop_loss" or "take_profit"
    current_price: float
    trigger_price: float
