"""Pydantic schemas for API request/response validation - Extended with subscription support."""
from pydantic import BaseModel, EmailStr, Field, validator, ConfigDict
from typing import Optional, Dict, Any, List
from datetime import datetime
from enum import Enum


class UserTier(str, Enum):
    """User subscription tier."""
    FREE = "free"
    PRO = "pro"
    ENTERPRISE = "enterprise"


class ProjectStatus(str, Enum):
    """Project generation status."""
    PENDING = "pending"
    PROCESSING = "processing"
    COMPLETED = "completed"
    FAILED = "failed"


class Platform(str, Enum):
    """Social media platform."""
    YOUTUBE = "youtube"
    TIKTOK = "tiktok"
    TWITTER = "twitter"
    FACEBOOK = "facebook"


# User Schemas
class UserBase(BaseModel):
    """Base user schema."""
    email: EmailStr
    username: str


class UserCreate(UserBase):
    """User creation schema."""
    password: str


class UserUpdate(BaseModel):
    """User update schema."""
    email: Optional[EmailStr] = None
    username: Optional[str] = None
    password: Optional[str] = None
    is_active: Optional[bool] = None
    is_admin: Optional[bool] = None
    tier: Optional[UserTier] = None


class UserResponse(UserBase):
    """User response schema."""
    id: str
    is_active: bool
    is_admin: bool
    tier: UserTier
    created_at: datetime
    
    model_config = ConfigDict(from_attributes=True)


class AdminStats(BaseModel):
    """Admin dashboard statistics."""
    total_users: int
    active_users: int
    total_projects: int
    completed_projects: int
    failed_projects: int
    total_api_keys: int


# Authentication Schemas
class Token(BaseModel):
    """JWT token response."""
    access_token: str
    refresh_token: Optional[str] = None
    token_type: str = "bearer"
    expires_in: int


class TokenData(BaseModel):
    """Token payload data."""
    user_id: Optional[str] = None


class LoginRequest(BaseModel):
    """Login request body."""
    username: str = Field(..., description="Username or email")
    password: str = Field(..., description="Password")


class RefreshTokenRequest(BaseModel):
    """Refresh token request."""
    refresh_token: str


# Audio Settings
class AudioSettings(BaseModel):
    """Audio generation settings."""
    duration: int = Field(default=30, ge=5, le=300, description="Audio duration in seconds")
    style: str = Field(default="cinematic", description="Music style/genre")
    tempo: Optional[int] = Field(default=None, ge=40, le=200, description="Tempo in BPM")
    mood: Optional[str] = Field(default=None, description="Mood/emotion")
    include_vocals: bool = Field(default=False, description="Include synthesized vocals")
    voice_prompt: Optional[str] = Field(default=None, description="Text for vocals")


# Video Settings
class VideoSettings(BaseModel):
    """Video generation settings."""
    resolution: str = Field(default="1080p", description="Video resolution")
    style: str = Field(default="realistic", description="Visual style")
    aspect_ratio: str = Field(default="16:9", description="Aspect ratio")
    fps: int = Field(default=30, ge=24, le=60, description="Frames per second")
    motion_intensity: str = Field(default="medium", description="Camera/object motion")


# Project Schemas
class ProjectCreate(BaseModel):
    """Project creation schema."""
    name: str = Field(..., min_length=1, max_length=200)
    prompt: str = Field(..., min_length=10, description="Text description of desired content")
    audio_settings: Optional[AudioSettings] = None
    video_settings: Optional[VideoSettings] = None


class ProjectResponse(BaseModel):
    """Project response schema."""
    id: str
    user_id: str
    name: str
    prompt: str
    status: ProjectStatus
    audio_settings: Optional[Dict[str, Any]] = None
    video_settings: Optional[Dict[str, Any]] = None
    audio_file: Optional[str] = None
    video_file: Optional[str] = None
    final_file: Optional[str] = None
    duration: Optional[float] = None
    resolution: Optional[str] = None
    sync_score: Optional[float] = None
    quality_score: Optional[float] = None
    created_at: datetime
    started_at: Optional[datetime] = None
    completed_at: Optional[datetime] = None
    error_message: Optional[str] = None
    
    model_config = ConfigDict(from_attributes=True)


class ProjectUpdate(BaseModel):
    """Project update schema."""
    name: Optional[str] = None
    status: Optional[ProjectStatus] = None


# Publication Schemas
class PublicationCreate(BaseModel):
    """Publication creation schema."""
    project_id: str
    platform: Platform
    title: Optional[str] = None
    description: Optional[str] = None
    tags: Optional[List[str]] = None
    scheduled_at: Optional[datetime] = None


class PublicationResponse(BaseModel):
    """Publication response schema."""
    id: str
    project_id: str
    platform: Platform
    status: str
    platform_post_id: Optional[str] = None
    post_url: Optional[str] = None
    title: Optional[str] = None
    description: Optional[str] = None
    tags: Optional[List[str]] = None
    scheduled_at: Optional[datetime] = None
    posted_at: Optional[datetime] = None
    views: int
    likes: int
    shares: int
    comments: int
    created_at: datetime
    
    model_config = ConfigDict(from_attributes=True)


# Generic Response
class MessageResponse(BaseModel):
    """Generic message response."""
    message: str
    detail: Optional[str] = None


class HealthResponse(BaseModel):
    """Health check response."""
    status: str
    service: str
    timestamp: datetime
    version: str


# Subscription Schemas
class SubscriptionResponse(BaseModel):
    """Subscription response schema."""
    id: str
    user_id: str
    plan: str
    status: str
    stripe_customer_id: Optional[str] = None
    stripe_subscription_id: Optional[str] = None
    current_period_start: Optional[datetime] = None
    current_period_end: Optional[datetime] = None
    cancel_at_period_end: bool = False
    trial_end: Optional[datetime] = None
    created_at: datetime
    
    model_config = ConfigDict(from_attributes=True)


class CheckoutSessionCreate(BaseModel):
    """Create checkout session request."""
    plan: str = Field(..., description="Plan to subscribe to (pro, enterprise)")
    success_url: str = Field(..., description="URL to redirect on success")
    cancel_url: str = Field(..., description="URL to redirect on cancel")
    
    @validator('plan')
    def validate_plan(cls, v):
        if v not in ['pro', 'enterprise']:
            raise ValueError('Plan must be pro or enterprise')
        return v


class CheckoutSessionResponse(BaseModel):
    """Checkout session response."""
    session_id: str
    url: str


class SubscriptionCancel(BaseModel):
    """Cancel subscription request."""
    immediately: bool = Field(default=False, description="Cancel immediately or at period end")


# Email & Password Reset Schemas
class EmailVerificationRequest(BaseModel):
    """Email verification request."""
    token: str


class PasswordResetRequest(BaseModel):
    """Password reset request."""
    email: EmailStr


class PasswordResetConfirm(BaseModel):
    """Password reset confirmation."""
    token: str
    new_password: str = Field(..., min_length=6)

