"""
=========================================
CV6 AI Trading OS
Dashboard — Pydantic Schemas (v2)
JSON-only. No frontend. No charts.
=========================================
"""

import time
from typing import List, Optional
from pydantic import BaseModel, Field


class FundsInfo(BaseModel):
    available_cash: float = 0.0
    used_margin:    float = 0.0
    total_funds:    float = 0.0
    collateral:     float = 0.0
    broker:         str   = ""


class PositionInfo(BaseModel):
    symbol:     str
    exchange:   str   = "NSE"
    quantity:   int   = 0
    avg_price:  float = 0.0
    ltp:        float = 0.0
    pnl:        float = 0.0
    pnl_pct:    float = 0.0
    product:    str   = "MIS"
    trade_type: str   = "BUY"
    broker:     str   = ""


class OrderInfo(BaseModel):
    order_id:   str
    symbol:     str
    trade_type: str   = "BUY"
    quantity:   int   = 0
    price:      float = 0.0
    status:     str   = "PENDING"
    order_type: str   = "MARKET"
    placed_at:  float = Field(default_factory=time.time)
    broker:     str   = ""


class PnLInfo(BaseModel):
    realized_pnl:   float = 0.0
    unrealized_pnl: float = 0.0
    total_pnl:      float = 0.0
    total_charges:  float = 0.0
    net_pnl:        float = 0.0
    winning_trades: int   = 0
    losing_trades:  int   = 0
    win_rate_pct:   float = 0.0


class RiskInfo(BaseModel):
    current_exposure:      float = 0.0
    margin_utilization_pct:float = 0.0
    open_risk:             float = 0.0
    daily_loss_limit:      float = 5000.0
    daily_loss_used:       float = 0.0
    risk_status:           str   = "OK"   # OK | WARNING | BREACH


class AIStatusInfo(BaseModel):
    enabled:             bool       = False
    active_models:       List[str]  = []
    last_signal:         str        = ""
    last_confidence:     float      = 0.0
    last_symbol:         str        = ""
    consensus_available: bool       = False


class BrokerStatusInfo(BaseModel):
    name:        str
    connected:   bool          = False
    latency_ms:  float         = 0.0
    last_ping:   Optional[float] = None
    error:       Optional[str]   = None


class MarketStatusInfo(BaseModel):
    is_open:    bool  = False
    session:    str   = "CLOSED"  # PRE_OPEN|OPEN|POST_CLOSE|CLOSED
    exchange:   str   = "NSE"
    open_time:  str   = "09:15"
    close_time: str   = "15:30"


class SystemHealthInfo(BaseModel):
    cpu_pct:           float = 0.0
    memory_pct:        float = 0.0
    disk_pct:          float = 0.0
    uptime_seconds:    float = 0.0
    websocket_clients: int   = 0
    active_streams:    int   = 0
    db_ok:             bool  = True
    status:            str   = "HEALTHY"  # HEALTHY|DEGRADED|CRITICAL


class DashboardResponse(BaseModel):
    success:       bool                  = True
    generated_at:  float                 = Field(default_factory=time.time)
    portfolio:     List[PositionInfo]    = []
    funds:         Optional[FundsInfo]   = None
    pnl:           Optional[PnLInfo]     = None
    risk:          Optional[RiskInfo]    = None
    open_positions:List[PositionInfo]    = []
    orders:        List[OrderInfo]       = []
    ai_status:     Optional[AIStatusInfo]= None
    broker_status: List[BrokerStatusInfo]= []
    market_status: Optional[MarketStatusInfo] = None
    system_health: Optional[SystemHealthInfo] = None
