from pydantic import BaseModel, Field, validator
from typing import Optional, Dict, Any
from datetime import datetime
from app.models.user_preference import ThemeMode, Language, NotificationFrequency

class NotificationSettings(BaseModel):
    email_notifications: Optional[bool] = None
    push_notifications: Optional[bool] = None
    sms_notifications: Optional[bool] = None
    email_frequency: Optional[NotificationFrequency] = None
    digest_frequency: Optional[NotificationFrequency] = None
    notification_preferences: Optional[Dict[str, bool]] = None

class PrivacySettings(BaseModel):
    profile_visibility: Optional[str] = Field(None, regex="^(public|private|friends_only)$")
    search_visibility: Optional[bool] = None
    show_online_status: Optional[bool] = None
    show_last_seen: Optional[bool] = None
    allow_friend_requests: Optional[bool] = None
    allow_messages_from_strangers: Optional[bool] = None
    show_email: Optional[bool] = None
    show_phone: Optional[bool] = None
    data_collection_consent: Optional[bool] = None
    analytics_tracking: Optional[bool] = None

class SecuritySettings(BaseModel):
    two_factor_enabled: Optional[bool] = None
    login_notifications: Optional[bool] = None
    unusual_activity_alerts: Optional[bool] = None
    password_expiry_reminder: Optional[bool] = None
    session_timeout: Optional[int] = Field(None, ge=5, le=1440)  # 5 minutes to 24 hours
    require_password_for_sensitive_actions: Optional[bool] = None

class ContentSettings(BaseModel):
    content_language: Optional[str] = None
    mature_content: Optional[bool] = None
    auto_play_videos: Optional[bool] = None
    high_contrast_mode: Optional[bool] = None
    reduce_motion: Optional[bool] = None
    font_size: Optional[str] = Field(None, regex="^(small|medium|large|extra_large)$")
    posts_per_page: Optional[int] = Field(None, ge=5, le=100)

class CommunicationSettings(BaseModel):
    preferred_contact_method: Optional[str] = Field(None, regex="^(email|phone|sms)$")
    marketing_consent: Optional[bool] = None
    newsletter_subscription: Optional[bool] = None
    survey_participation: Optional[bool] = None
    beta_program: Optional[bool] = None

class PreferenceUpdate(BaseModel):
    # UI/UX Preferences
    theme: Optional[ThemeMode] = None
    language: Optional[Language] = None
    timezone: Optional[str] = None
    date_format: Optional[str] = None
    time_format: Optional[str] = Field(None, regex="^(12|24)$")
    
    # Notification Preferences
    notification_settings: Optional[NotificationSettings] = None
    
    # Privacy Preferences
    privacy_settings: Optional[PrivacySettings] = None
    
    # Security Preferences
    security_settings: Optional[SecuritySettings] = None
    
    # Content Preferences
    content_preferences: Optional[ContentSettings] = None
    
    # Communication Preferences
    communication_settings: Optional[CommunicationSettings] = None
    
    # App-Specific Settings
    app_settings: Optional[Dict[str, Any]] = None
    
    # Custom Preferences
    custom_preferences: Optional[Dict[str, Any]] = None

    @validator('timezone')
    def validate_timezone(cls, v):
        if v:
            # Basic timezone validation - in production use pytz
            common_timezones = [
                'UTC', 'US/Eastern', 'US/Central', 'US/Mountain', 'US/Pacific',
                'Europe/London', 'Europe/Paris', 'Europe/Berlin', 'Asia/Tokyo',
                'Asia/Shanghai', 'Australia/Sydney'
            ]
            if v not in common_timezones and not v.startswith('UTC'):
                raise ValueError('Invalid timezone')
        return v

class PreferenceResponse(BaseModel):
    id: str
    user_id: str
    theme: ThemeMode
    language: Language
    timezone: str
    date_format: str
    time_format: str
    email_notifications: bool
    push_notifications: bool
    sms_notifications: bool
    notification_preferences: Dict[str, bool]
    email_frequency: NotificationFrequency
    digest_frequency: NotificationFrequency
    privacy_settings: Dict[str, Any]
    security_settings: Dict[str, Any]
    content_preferences: Dict[str, Any]
    communication_settings: Dict[str, Any]
    app_settings: Dict[str, Any]
    custom_preferences: Dict[str, Any]
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True

class BulkPreferenceUpdate(BaseModel):
    updates: Dict[str, Any]  # Category -> settings mapping
    
    @validator('updates')
    def validate_updates(cls, v):
        allowed_categories = [
            'notification_preferences', 'privacy_settings', 'security_settings',
            'content_preferences', 'communication_settings', 'app_settings',
            'custom_preferences'
        ]
        for category in v.keys():
            if category not in allowed_categories:
                raise ValueError(f'Invalid preference category: {category}')
        return v

class PreferenceExportResponse(BaseModel):
    preferences: Dict[str, Any]
    exported_at: datetime
    user_id: str

class PreferenceImportRequest(BaseModel):
    preferences: Dict[str, Any]
    overwrite_existing: bool = False

class PreferenceTemplate(BaseModel):
    name: str
    description: Optional[str] = None
    template_data: Dict[str, Any]
    is_public: bool = False

class PreferenceTemplateResponse(BaseModel):
    id: str
    name: str
    description: Optional[str] = None
    template_data: Dict[str, Any]
    is_public: bool
    created_by: str
    created_at: datetime
    usage_count: int = 0

    class Config:
        from_attributes = True
