from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any


@dataclass
class StrategyManifest:
    strategy_id: str
    name: str
    version: str
    kind: str
    entrypoint: str
    description: str = ""
    author: str = ""
    tags: list[str] = field(default_factory=list)
    capabilities: list[str] = field(default_factory=list)
    supported_symbols: list[str] = field(default_factory=list)
    supported_timeframes: list[str] = field(default_factory=list)
    params_schema: dict[str, Any] = field(default_factory=dict)
    default_mode: str = "builtin"
    trust_level: str = "builtin"


@dataclass
class StrategyInitContext:
    strategy_id: str
    strategy_version: str
    config_revision: str
    symbol: str
    timeframe: str
    mode: str
    config: dict[str, Any] = field(default_factory=dict)
    shared_features: dict[str, Any] = field(default_factory=dict)
    env: dict[str, Any] = field(default_factory=dict)


@dataclass
class MarketSnapshot:
    symbol: str
    timeframe: str
    timestamp_ms: int
    bars: list[dict[str, Any]] = field(default_factory=list)
    params: dict[str, Any] = field(default_factory=dict)
    bid: float | None = None
    ask: float | None = None
    mid: float | None = None
    spread: float | None = None
    indicators: dict[str, Any] = field(default_factory=dict)
    regime: dict[str, Any] = field(default_factory=dict)
    session: dict[str, Any] = field(default_factory=dict)
    macro: dict[str, Any] = field(default_factory=dict)
    vol_ratio: float = 1.0
    session_mode: str = "NORMAL"


@dataclass
class StrategyIntent:
    strategy_id: str
    strategy_version: str
    config_revision: str
    instance_id: str
    action: str
    side: str
    confidence: float
    priority: int = 50
    ttl_ms: int = 30000
    reason: str = ""
    tags: list[str] = field(default_factory=list)
    entry_plan: dict[str, Any] = field(default_factory=dict)
    exit_plan: dict[str, Any] = field(default_factory=dict)
    diagnostics: dict[str, Any] = field(default_factory=dict)


@dataclass
class StrategyRiskOpinion:
    allow: bool
    severity: str = "INFO"
    recommended_action: str = "ALLOW"
    score: float = 0.0
    reasons: list[str] = field(default_factory=list)
    overlays: dict[str, Any] = field(default_factory=dict)


@dataclass
class TradeIntent:
    strategy_id: str
    symbol: str
    instance_id: str
    action: str
    side: str
    quantity: float | None = None
    entry_price: float | None = None
    stop_loss: float | None = None
    take_profit: float | None = None
    time_in_force: str = "GTC"
    metadata: dict[str, Any] = field(default_factory=dict)


@dataclass
class RiskSnapshot:
    timestamp_ms: int
    symbol: str
    account_id: str
    risk_state: str
    block_new_orders: bool = False
    reduce_only: bool = False
    margin_ratio: float | None = None
    exposure_ratio: float | None = None
    spread_risk: float | None = None
    volatility_risk: float | None = None
    event_risk: float | None = None
    reasons: list[str] = field(default_factory=list)
    metrics: dict[str, Any] = field(default_factory=dict)


@dataclass
class PortfolioStateView:
    account_id: str
    symbol: str
    position_side: str = "FLAT"
    position_size: float = 0.0
    avg_entry_price: float | None = None
    unrealized_pnl: float | None = None
    realized_pnl: float | None = None
    risk_budget: dict[str, Any] = field(default_factory=dict)
    open_orders: list[dict[str, Any]] = field(default_factory=list)


@dataclass
class RuntimeInstance:
    instance_id: str
    strategy_id: str
    strategy_name: str = ""
    strategy_version: str = "legacy"
    allocation: float = 0.0
    status: str = "running"
    role: str = "live_support"
    config_revision: str = "manual"
    param_overrides: dict[str, Any] = field(default_factory=dict)
    template_snapshot: dict[str, Any] = field(default_factory=dict)
    metadata: dict[str, Any] = field(default_factory=dict)


@dataclass
class SchedulerSnapshot:
    mode: str = "idle"
    arbiter: str = "allocation-weighted"
    reason: str = "no_running_instances"
    active_instance_ids: list[str] = field(default_factory=list)
    active_strategy_ids: list[str] = field(default_factory=list)
    instance_weights: dict[str, float] = field(default_factory=dict)
    strategy_weights: dict[str, float] = field(default_factory=dict)
    strategy_instance_map: dict[str, list[str]] = field(default_factory=dict)
    config_revision: str = "manual"
    updated_at: str = ""


@dataclass
class AggregatedIntentContribution:
    instance_id: str
    strategy_id: str
    action: str
    side: str
    weight: float
    confidence: float
    signed_score: float
    reason: str = ""


@dataclass
class AggregatedIntent:
    action: str
    side: str
    net_score: float
    confidence: float
    contributors: list[AggregatedIntentContribution] = field(default_factory=list)
    blocked_reasons: list[str] = field(default_factory=list)
    selected_instance_id: str = ""
    selected_strategy_id: str = ""
    metadata: dict[str, Any] = field(default_factory=dict)


@dataclass
class StrategyHealth:
    strategy_id: str
    loaded: bool = False
    healthy: bool = True
    last_error: str | None = None
    last_run_at_ms: int | None = None
    last_latency_ms: float | None = None
    consecutive_failures: int = 0
    config_revision: str = "manual"
    strategy_version: str = "legacy"
