"""Pydantic interface contracts for all internal data hand-offs."""

from __future__ import annotations

from datetime import datetime, timezone
from decimal import Decimal
from enum import Enum
from typing import Literal
from uuid import UUID, uuid4

from pydantic import BaseModel, Field


class OrderState(str, Enum):
    SUBMITTED = "SUBMITTED"
    PARTIAL_ACTIVE = "PARTIAL_ACTIVE"
    PARTIAL_TIMEOUT = "PARTIAL_TIMEOUT"
    FILLED = "FILLED"
    CANCELLED = "CANCELLED"
    REJECTED = "REJECTED"
    SIMULATED = "SIMULATED"


class TradeSignal(BaseModel):
    signal_id: UUID = Field(default_factory=uuid4)
    symbol: str
    direction: Literal["buy", "sell", "hold"]
    strategy_tier: Literal["core", "pump", "broad", "micro"]
    confidence: float = Field(ge=0.0, le=1.0)
    suggested_quantity_pct: float = Field(ge=0.0, le=100.0)
    max_hold_seconds: int | None = None
    model_version: str = "rules-v1"
    emitted_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))


class RiskDecision(BaseModel):
    signal_id: UUID
    approved: bool
    adjusted_quantity: Decimal | None = None
    stop_loss_price: Decimal | None = None
    rejection_reason: str | None = None
    rejection_step: int | None = None


class OrderResult(BaseModel):
    order_id: str | None = None
    client_order_id: str
    status: OrderState
    filled_qty: Decimal = Decimal("0")
    avg_price: Decimal = Decimal("0")
    fee: Decimal = Decimal("0")
    mode: Literal["draft", "live"] = "draft"
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))


class PositionInfo(BaseModel):
    symbol: str
    mode: Literal["draft", "live"]
    quantity: Decimal
    avg_entry_price: Decimal
    current_price: Decimal | None = None
    unrealised_pnl: Decimal | None = None
    strategy_tier: Literal["core", "pump", "broad", "micro"]
    stop_loss_price: Decimal | None = None
    take_profit_price: Decimal | None = None
    max_hold_until: datetime | None = None
    exchange_order_id: str | None = None


class AlertEvent(BaseModel):
    event_type: str
    symbol: str | None = None
    severity: Literal["info", "warn", "critical"] = "info"
    message: str
    mode: Literal["draft", "live"] = "draft"
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))


class HealthStatus(BaseModel):
    status: Literal["healthy", "degraded", "unhealthy"]
    mode: Literal["draft", "live"]
    reconciliation_complete: bool = False
    components: dict[str, str] = Field(default_factory=dict)
    uptime_seconds: float = 0.0
