from __future__ import annotations

from pydantic import BaseModel


class CryptoTraderJournalStatus(BaseModel):
    exists: bool
    fresh: bool
    age_seconds: int | None = None
    size_bytes: int = 0


class CryptoTraderStrategyStatus(BaseModel):
    strategy_id: str
    running: bool = False
    paper_only: bool = True
    env_ok: bool = False
    cmd_ok: bool = False
    pid: int | None = None
    runtime_dir: str | None = None
    trade_journal: str | None = None
    signal_journal: str | None = None
    journals: dict[str, CryptoTraderJournalStatus] = {}


class HyperliquidPosition(BaseModel):
    coin: str
    strategy_id: str
    mode: str = "paper"
    side: str = "long"
    entry_price: str | None = None
    mark_price: str | None = None
    size: str | None = None
    notional_usd: str | None = None
    unrealized_pnl_usd: str | None = None
    unrealized_pnl_pct: str | None = None
    stop_loss: str | None = None
    take_profit: str | None = None
    mfe_pct: str | None = None
    mae_pct: str | None = None
    ticks_held: int | None = None
    opened_at: str | None = None
    status: str = "open"


class HyperliquidClosedTrade(BaseModel):
    trade_id: str
    timestamp: str | None = None
    coin: str
    strategy_id: str
    side: str = "long"
    size: str | None = None
    entry_price: str | None = None
    exit_price: str | None = None
    net_pnl_usd: str | None = None
    gross_pnl_usd: str | None = None
    fees_usd: str | None = None
    funding_cost_usd: str | None = None
    exit_reason: str | None = None
    candles_held: int | None = None
    mode: str = "paper"


class HyperliquidRiskCheck(BaseModel):
    key: str
    label: str
    status: str
    detail: str | None = None


class HyperliquidPerformancePoint(BaseModel):
    timestamp: str
    paper_pnl_usd: str
    live_equity_usd: str | None = None


class HyperliquidStrategyPerformance(BaseModel):
    strategy_id: str
    label: str
    closed_trades: int
    winrate_pct: str | None = None
    net_pnl_usd: str
    avg_pnl_usd: str | None = None
    status: str
    note: str


class HyperliquidWarningExplanation(BaseModel):
    key: str
    severity: str
    title: str
    explanation: str
    action: str


class CryptoTraderSignal(BaseModel):
    signal_id: str
    timestamp: str | None = None
    coin: str
    strategy_id: str
    signal: str
    confidence: str | None = None
    final_decision: str | None = None
    reason_summary: str
    horizon: str = "short_term"
    mode: str = "paper_only"
    data_quality: str = "unknown"
    approval_status: str = "not_requested"
    execution_allowed: bool = False


class CryptoTraderScorecard(BaseModel):
    title: str
    status: str
    mode: str
    closed_trades: int = 0
    net_pnl_usd: str | None = None
    winrate_pct: str | None = None
    profit_factor: str | None = None
    blockers: list[str] = []
    live_allowed: bool = False


class TradeIntent(BaseModel):
    intent_id: str
    created_at: str | None = None
    expires_at: str | None = None
    portfolio_id: str = "hyperliquid"
    source_engine: str = "CryptoTrader"
    strategy_id: str
    coin: str
    side: str = "long"
    signal: str = "BUY"
    confidence: str | None = None
    notional_usd: str | None = None
    entry_context: str
    stop_loss: str | None = None
    take_profit: str | None = None
    risk_usd: str | None = None
    expected_move_vs_cost: str | None = None
    status: str = "proposed"
    approval_status: str = "awaiting_approval"
    execution_allowed: bool = False
    warnings: list[str] = []


class TradeApprovalRequest(BaseModel):
    intent_id: str
    decision: str
    note: str = ""
    confirm: bool = False


class TradeApprovalResponse(BaseModel):
    status: str
    approval_id: str
    intent_id: str
    decision: str
    message: str
    execution_allowed: bool = False
    audit_path: str | None = None


class CryptoTraderStatus(BaseModel):
    bridge_status: str
    runtime_root: str
    source: str
    generated_at: str
    mode: str
    live_allowed: bool
    safety_summary: str
    processes: list[CryptoTraderStrategyStatus]
    open_positions_count: int
    signals_count: int
    scorecards_count: int
    warnings: list[str] = []


class HyperliquidPortfolioSnapshot(BaseModel):
    portfolio_id: str = "hyperliquid"
    label: str = "Hyperliquid"
    mode: str = "paper_only"
    base_currency: str = "USDC"
    live_allowed: bool = False
    kill_switch_status: str = "unknown"
    open_positions: list[HyperliquidPosition] = []
    recent_closed_trades: list[HyperliquidClosedTrade] = []
    risk_checks: list[HyperliquidRiskCheck] = []
    performance_points: list[HyperliquidPerformancePoint] = []
    strategy_performance: list[HyperliquidStrategyPerformance] = []
    warning_explanations: list[HyperliquidWarningExplanation] = []
    exposure_notional_usd: str = "0.00"
    unrealized_pnl_usd: str = "0.00"
    realized_pnl_usd: str = "0.00"
    closed_trades_count: int = 0
    winrate_pct: str | None = None
    experimental_legacy_realized_pnl_usd: str | None = None
    experimental_legacy_closed_trades_count: int | None = None
    experimental_legacy_winrate_pct: str | None = None
    free_usdc: str | None = None
    equity_usdc: str | None = None
    margin_usage_pct: str | None = None
    open_orders_count: int = 0
    stops_missing_count: int = 0
    reconcile_status: str = "unknown"
    paper_trading_note: str = "Headline PnL uses recent true lifecycle paper exits; legacy synthetic paper exits are shown only as experimental context."
    metric_basis: str = "recent_true_lifecycle_window"
    approval_mode_recommendation: str = "Approval queue is for supervised live pilot only; normal paper/autonomous research should not wait for manual approval."
    approval_boundary: str = "Dashboard approves intents only; CryptoTrader must re-check gates before any execution."


class CryptoTraderSnapshot(BaseModel):
    status: CryptoTraderStatus
    portfolio: HyperliquidPortfolioSnapshot
    signals: list[CryptoTraderSignal]
    trade_intents: list[TradeIntent] = []
    scorecards: list[CryptoTraderScorecard]
    daily_report_excerpt: list[str] = []
