from pydantic import BaseModel, Field
from typing import Optional, List
from datetime import datetime
from enum import Enum


class TradeAction(str, Enum):
    BUY = "BUY"
    SELL = "SELL"


class Recommendation(str, Enum):
    BUY = "BUY"
    SELL = "SELL"
    HOLD = "HOLD"


class RiskLevel(str, Enum):
    LOW = "LOW"
    MEDIUM = "MEDIUM"
    HIGH = "HIGH"


class PriceData(BaseModel):
    time: int
    open: float
    high: float
    low: float
    close: float
    volume: Optional[float] = None


class TradeCreate(BaseModel):
    action: TradeAction
    quantity: float
    price: float


class TradeResponse(BaseModel):
    id: int
    simulation_id: int
    action: TradeAction
    quantity: float
    price: float
    total: float
    pnl: Optional[float] = None
    timestamp: datetime

    class Config:
        from_attributes = True


class PositionResponse(BaseModel):
    symbol: str
    quantity: float
    avg_price: float
    current_price: float
    unrealized_pnl: float
    unrealized_pnl_percent: float

    class Config:
        from_attributes = True


class PortfolioResponse(BaseModel):
    cash: float
    initial_capital: float
    total_value: float
    total_pnl: float
    total_pnl_percent: float
    position: Optional[PositionResponse] = None
    trades: List[TradeResponse] = []


class MarketDataResponse(BaseModel):
    symbol: str = "XAU/USD"
    price: float
    change: float
    change_percent: float
    high_24h: float
    low_24h: float
    volume: float


class SupportResistance(BaseModel):
    support: List[float] = []
    resistance: List[float] = []


class AIAnalysisRequest(BaseModel):
    price_data: List[PriceData]
    indicators: List[dict]
    current_price: float


class AIAnalysisResponse(BaseModel):
    recommendation: Recommendation
    confidence: float = Field(..., ge=0, le=100)
    reasoning: str
    support_resistance: SupportResistance
    risk_level: RiskLevel


class IndicatorData(BaseModel):
    time: int
    value: float


# News and Sentiment Schemas
class Sentiment(str, Enum):
    POSITIVE = "POSITIVE"
    NEGATIVE = "NEGATIVE"
    NEUTRAL = "NEUTRAL"


class NewsArticle(BaseModel):
    id: str
    source: str
    title: str
    description: Optional[str] = None
    url: str
    published_at: datetime
    sentiment: Sentiment
    sentiment_score: float = Field(..., ge=-1, le=1)
    impact_on_gold: str  # HIGH, MEDIUM, LOW
    relevance_score: float = Field(..., ge=0, le=1)
    category: str  # MONETARY_POLICY, GEOPOLITICS, ECONOMIC_DATA, etc.


class NewsFeedResponse(BaseModel):
    articles: List[NewsArticle]
    total_count: int
    bullish_count: int
    bearish_count: int
    neutral_count: int
    overall_sentiment: Sentiment
    avg_sentiment_score: float


class EconomicEvent(BaseModel):
    id: str
    title: str
    country: str
    currency: str
    event_date: datetime
    importance: str  # HIGH, MEDIUM, LOW
    forecast: Optional[str] = None
    previous: Optional[str] = None
    actual: Optional[str] = None
    impact_on_gold: str


class EconomicCalendarResponse(BaseModel):
    events: List[EconomicEvent]
    upcoming_high_impact: int


# Alert Schemas
class AlertType(str, Enum):
    PRICE_SPIKE = "PRICE_SPIKE"
    PRICE_DROP = "PRICE_DROP"
    NEWS_BREAKING = "NEWS_BREAKING"
    SUPPORT_BREACH = "SUPPORT_BREACH"
    RESISTANCE_BREACH = "RESISTANCE_BREACH"
    HIGH_VOLATILITY = "HIGH_VOLATILITY"
    ECONOMIC_EVENT = "ECONOMIC_EVENT"


class AlertSeverity(str, Enum):
    CRITICAL = "CRITICAL"
    HIGH = "HIGH"
    MEDIUM = "MEDIUM"
    LOW = "LOW"


class Alert(BaseModel):
    id: str
    type: AlertType
    severity: AlertSeverity
    title: str
    message: str
    price: Optional[float] = None
    change_percent: Optional[float] = None
    timestamp: datetime
    related_news: Optional[List[str]] = []  # URLs to related news
    action_required: bool = False


class AlertsResponse(BaseModel):
    alerts: List[Alert]
    critical_count: int
    unread_count: int


# News-Price Correlation
class NewsPriceCorrelation(BaseModel):
    news_id: str
    news_title: str
    news_time: datetime
    price_before: float
    price_after: float
    price_change: float
    price_change_percent: float
    time_delta_minutes: int
    correlation_strength: str  # STRONG, MODERATE, WEAK


class CorrelationAnalysisResponse(BaseModel):
    correlations: List[NewsPriceCorrelation]
    significant_events: int
    avg_price_impact: float


# Phase 1: Daily Helper Schemas

class UserProfileCreate(BaseModel):
    email: Optional[str] = None
    username: Optional[str] = None
    timezone: str = "UTC"
    preferred_trading_start: str = "09:00"
    preferred_trading_end: str = "17:00"
    risk_tolerance: str = "moderate"
    trading_style: str = "day_trader"
    daily_target: Optional[float] = None
    max_loss: Optional[float] = None


class UserProfileUpdate(BaseModel):
    timezone: Optional[str] = None
    preferred_trading_start: Optional[str] = None
    preferred_trading_end: Optional[str] = None
    risk_tolerance: Optional[str] = None
    trading_style: Optional[str] = None
    daily_target: Optional[float] = None
    max_loss: Optional[float] = None
    notifications_enabled: Optional[bool] = None
    email_reports: Optional[bool] = None
    sms_enabled: Optional[bool] = None
    push_notifications: Optional[bool] = None
    phone_number: Optional[str] = None


class UserProfileResponse(BaseModel):
    id: int
    email: Optional[str]
    username: Optional[str]
    timezone: str
    preferred_trading_start: str
    preferred_trading_end: str
    risk_tolerance: str
    trading_style: str
    daily_target: Optional[float]
    max_loss: Optional[float]
    notifications_enabled: bool
    email_reports: bool
    sms_enabled: bool
    push_notifications: bool
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True


class DailyRoutineCreate(BaseModel):
    routine_type: str  # morning, active_trading, evening
    scheduled_time: str  # HH:MM
    tasks: List[str] = []
    enabled: bool = True


class DailyRoutineUpdate(BaseModel):
    scheduled_time: Optional[str] = None
    tasks: Optional[List[str]] = None
    enabled: Optional[bool] = None


class DailyRoutineResponse(BaseModel):
    id: int
    routine_type: str
    scheduled_time: str
    tasks: List[str]
    enabled: bool
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True


class RoutineExecutionResponse(BaseModel):
    id: int
    routine_id: int
    executed_at: datetime
    completion_status: str
    tasks_completed: List[str]
    execution_notes: Optional[str]

    class Config:
        from_attributes = True


class NotificationCreate(BaseModel):
    notification_type: str
    title: str
    message: str
    priority: str = "normal"
    delivery_method: str = "push"
    data: Optional[dict] = None


class NotificationResponse(BaseModel):
    id: int
    notification_type: str
    title: str
    message: str
    priority: str
    delivery_method: str
    read: bool
    created_at: datetime
    read_at: Optional[datetime]

    class Config:
        from_attributes = True


class NotificationListResponse(BaseModel):
    notifications: List[NotificationResponse]
    unread_count: int
    total_count: int


class ChecklistItem(BaseModel):
    id: str
    title: str
    completed: bool = False
    completed_at: Optional[datetime] = None


class DailyChecklistCreate(BaseModel):
    checklist_type: str  # morning, active_trading, evening, all
    items: Optional[List[ChecklistItem]] = None
    notes: Optional[str] = None


class DailyChecklistUpdate(BaseModel):
    items: Optional[List[ChecklistItem]] = None
    notes: Optional[str] = None


class DailyChecklistResponse(BaseModel):
    id: int
    checklist_date: str  # ISO date string
    checklist_type: str
    items: List[ChecklistItem]
    completion_percentage: float
    notes: Optional[str]
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True


class HabitTrackerCreate(BaseModel):
    habit_name: str
    frequency: str = "daily"  # daily, weekly


class HabitTrackerResponse(BaseModel):
    id: int
    habit_name: str
    frequency: str
    current_streak: int
    longest_streak: int
    total_completions: int
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True


class HabitCompletionRequest(BaseModel):
    habit_id: int
    completion_date: Optional[str] = None  # ISO date string, defaults to today


# ============================================================================
# INDICATOR PREFERENCES SCHEMAS
# ============================================================================

class IndicatorParameters(BaseModel):
    """Common indicator parameters"""
    period: Optional[int] = None
    length: Optional[int] = None
    multiplier: Optional[float] = None
    # Add more as needed


class IndicatorPreferenceCreate(BaseModel):
    indicator_name: str = Field(..., description="Name of the indicator (SMA, EMA, RSI, etc.)")
    enabled: bool = True
    parameters: Optional[dict] = None
    priority: int = Field(default=0, description="Higher priority = more important in AI analysis")
    notes: Optional[str] = None


class IndicatorPreferenceUpdate(BaseModel):
    enabled: Optional[bool] = None
    parameters: Optional[dict] = None
    priority: Optional[int] = None
    notes: Optional[str] = None


class IndicatorPreferenceResponse(BaseModel):
    id: int
    user_id: Optional[str]
    indicator_name: str
    enabled: bool
    parameters: Optional[dict]
    priority: int
    notes: Optional[str]
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True


class IndicatorPreferencesListResponse(BaseModel):
    preferences: List[IndicatorPreferenceResponse]
    total: int


# ============================================================================
# AI PLAN GENERATION SCHEMAS
# ============================================================================

class MarketBias(str, Enum):
    BULLISH = "BULLISH"
    BEARISH = "BEARISH"
    NEUTRAL = "NEUTRAL"


class AIPlanGenerationRequest(BaseModel):
    """Request to generate an AI trading plan"""
    current_price: float = Field(..., description="Current market price")
    user_capital: Optional[float] = Field(None, description="User's available capital")
    risk_tolerance: Optional[str] = Field("moderate", description="conservative, moderate, aggressive")
    use_indicator_preferences: bool = Field(True, description="Use user's saved indicator preferences")
    price_data: Optional[List[PriceData]] = Field(None, description="Recent price data for analysis")
    indicators_data: Optional[dict] = Field(None, description="Current indicator values")


class AIPlanGenerationResponse(BaseModel):
    """AI-generated trading plan"""
    id: int
    plan_date: str  # ISO date
    market_bias: MarketBias
    confidence: float  # 0-100
    daily_target: Optional[float]
    max_loss: Optional[float]
    entry_zone_min: Optional[float]
    entry_zone_max: Optional[float]
    target_price: Optional[float]
    stop_loss: Optional[float]
    support_levels: List[float]
    resistance_levels: List[float]
    max_trades: int
    trading_notes: Optional[str]
    indicators_used: List[str]
    reasoning: Optional[str]
    market_conditions: Optional[dict]
    ai_model: Optional[str]
    created_at: datetime

    class Config:
        from_attributes = True


class AIPlanFeedback(BaseModel):
    """User feedback on AI plan accuracy"""
    plan_id: int
    accepted: bool
    modified: bool = False
    feedback: Optional[str] = None
