from pydantic import BaseModel
from typing import Optional, List, Dict, Any
from datetime import datetime
from enum import Enum


class AssetClass(str, Enum):
    ENERGY = "energy"
    METALS = "metals"
    AGRICULTURE = "agriculture"
    EQUITIES = "equities"
    INDICES = "indices"
    FOREX = "forex"
    CRYPTO = "crypto"
    RATES = "rates"


class RiskLevel(str, Enum):
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"
    EXTREME = "extreme"


class GeopoliticalCategory(str, Enum):
    MILITARY = "military"
    SANCTIONS = "sanctions"
    ELECTIONS = "elections"
    NATURAL_DISASTER = "natural_disaster"
    HEALTH_CRISIS = "health_crisis"
    RESOURCE_SCARCITY = "resource_scarcity"
    TRADE_WAR = "trade_war"
    ENERGY_CRISIS = "energy_crisis"
    POLITICAL_SPEECH = "political_speech"
    FINANCIAL_CRISIS = "financial_crisis"


class GeoEvent(BaseModel):
    id: str
    title: str
    summary: str
    category: GeopoliticalCategory
    date: datetime
    source: str
    impact_score: float  # -1.0 to 1.0
    asset_impacts: Dict[AssetClass, float]  # impact per asset class
    tags: List[str]
    is_processed: bool = False


class MarketQuote(BaseModel):
    symbol: str
    name: str
    price: float
    change: float
    change_pct: float
    volume: int
    iv: Optional[float] = None  # implied volatility
    asset_class: AssetClass
    timestamp: datetime


class OptionsContract(BaseModel):
    symbol: str
    underlying: str
    expiry: str
    strike: float
    option_type: str  # call / put
    bid: float
    ask: float
    last: float
    volume: int
    open_interest: int
    iv: float
    delta: float
    gamma: float
    theta: float
    vega: float
    rho: float


class TradeIdea(BaseModel):
    id: str
    title: str
    rationale: str
    asset_class: AssetClass
    underlying: str
    strategy: str  # e.g. "Bull Call Spread", "Long Put", "Straddle"
    legs: List[Dict[str, Any]]
    max_loss: float
    max_gain: Optional[float]
    breakeven: List[float]
    horizon_days: int
    confidence: float  # 0-100
    geo_trigger: Optional[str]
    risk_level: RiskLevel
    capital_required: float
    created_at: datetime


class BacktestParams(BaseModel):
    start_date: str
    end_date: str
    strategy: str
    underlying: str
    geo_filters: Optional[List[GeopoliticalCategory]] = None
    capital: float = 1000.0


class BacktestResult(BaseModel):
    params: BacktestParams
    trades: List[Dict[str, Any]]
    total_return: float
    win_rate: float
    max_drawdown: float
    sharpe_ratio: float
    profit_factor: float
    equity_curve: List[Dict[str, Any]]


class EconomicEvent(BaseModel):
    id: str
    title: str
    country: str
    date: datetime
    importance: str  # low / medium / high
    previous: Optional[str]
    forecast: Optional[str]
    actual: Optional[str]
    asset_impact: List[AssetClass]


class PortfolioPosition(BaseModel):
    id: str
    trade_idea_id: Optional[str]
    symbol: str
    strategy: str
    entry_date: datetime
    expiry: str
    legs: List[Dict[str, Any]]
    capital_invested: float
    current_value: float
    pnl: float
    pnl_pct: float
    status: str  # open / closed / expired


class GeoPatternMatch(BaseModel):
    pattern_id: str
    description: str
    historical_date: datetime
    current_similarity: float
    historical_outcome: str
    suggested_trades: List[str]
    asset_class: AssetClass
