"""
Pydantic schemas for user data features.

Covers sessions, decks, replays, cards, groups, networks, preferences, and activity logs.
"""
from pydantic import BaseModel, Field, ConfigDict
from typing import Optional, List, Dict, Any
from datetime import datetime
from enum import Enum


# ===== Enum Types =====

class DeckVersionStatus(str, Enum):
    DRAFT = "DRAFT"
    FINAL = "FINAL"
    ARCHIVED = "ARCHIVED"


class GameReplayStatus(str, Enum):
    IN_PROGRESS = "IN_PROGRESS"
    COMPLETED = "COMPLETED"
    FAILED = "FAILED"
    CANCELLED = "CANCELLED"


class GameOutcomeType(str, Enum):
    WIN = "WIN"
    LOSS = "LOSS"
    CONCESSION = "CONCESSION"
    DISCONNECT = "DISCONNECT"


class GroupMemberRole(str, Enum):
    OWNER = "OWNER"
    ADMIN = "ADMIN"
    MEMBER = "MEMBER"


class NetworkMemberRole(str, Enum):
    OWNER = "OWNER"
    ADMIN = "ADMIN"
    MEMBER = "MEMBER"


class UserPreferenceTheme(str, Enum):
    LIGHT = "light"
    DARK = "dark"
    SYSTEM = "system"


class ActivityType(str, Enum):
    LOGIN = "LOGIN"
    LOGOUT = "LOGOUT"
    DECK_EDIT = "DECK_EDIT"
    GAME_PLAYED = "GAME_PLAYED"
    CARD_ACQUIRED = "CARD_ACQUIRED"
    CARD_TRADED = "CARD_TRADED"
    GROUP_CREATED = "GROUP_CREATED"
    GROUP_JOINED = "GROUP_JOINED"


# ===== Session Schemas =====

class SessionResponse(BaseModel):
    """User session response."""
    id: int
    user_id: int
    ip_address: Optional[str] = None
    user_agent: Optional[str] = None
    created_at: datetime
    expires_at: datetime
    is_active: bool
    
    model_config = ConfigDict(from_attributes=True)


class SessionCleanupResponse(BaseModel):
    """Response after cleaning expired sessions."""
    cleaned_count: int
    message: str


# ===== Deck Version Schemas =====

class DeckVersionCreate(BaseModel):
    """Deck version creation request."""
    content: str = Field(..., min_length=1)
    status: DeckVersionStatus = DeckVersionStatus.DRAFT
    comment: Optional[str] = None


class DeckVersionUpdate(BaseModel):
    """Deck version update request."""
    content: Optional[str] = None
    status: Optional[DeckVersionStatus] = None
    comment: Optional[str] = None


class DeckVersionResponse(BaseModel):
    """Deck version response."""
    id: int
    deck_id: int
    version_number: int
    content: str
    status: str
    comment: Optional[str]
    created_at: datetime
    
    model_config = ConfigDict(from_attributes=True)


class DeckVersionListResponse(BaseModel):
    """List of deck versions."""
    versions: List[DeckVersionResponse]
    total: int


# ===== Game Replay Schemas =====

class GameReplayCreate(BaseModel):
    """Game replay creation request."""
    game_uuid: str = Field(..., min_length=36, max_length=36)
    room_id: Optional[int] = None
    game_type: Optional[str] = None
    format: Optional[str] = None
    duration_seconds: Optional[int] = None
    start_time: datetime
    end_time: Optional[datetime] = None
    status: GameReplayStatus = GameReplayStatus.IN_PROGRESS
    replay_data: Optional[Dict[str, Any]] = None


class GameReplayUpdate(BaseModel):
    """Game replay update request."""
    room_id: Optional[int] = None
    game_type: Optional[str] = None
    format: Optional[str] = None
    duration_seconds: Optional[int] = None
    end_time: Optional[datetime] = None
    status: Optional[GameReplayStatus] = None
    replay_data: Optional[Dict[str, Any]] = None


class GameReplayResponse(BaseModel):
    """Game replay response."""
    id: int
    game_uuid: str
    room_id: Optional[int]
    game_type: Optional[str]
    format: Optional[str]
    duration_seconds: Optional[int]
    start_time: datetime
    end_time: Optional[datetime]
    status: str
    replay_data: Optional[Dict[str, Any]]
    created_at: datetime
    updated_at: datetime
    players: List[Dict[str, Any]] = []
    
    model_config = ConfigDict(from_attributes=True)


class GameReplayListResponse(BaseModel):
    """List of game replays."""
    replays: List[GameReplayResponse]
    total: int
    page: int
    page_size: int
    total_pages: int


# ===== Game Outcome Schemas =====

class GameOutcomeCreate(BaseModel):
    """Game outcome creation request."""
    game_uuid: str
    outcome: GameOutcomeType
    opponent_id: Optional[int] = None
    format: Optional[str] = None
    rating_before: Optional[int] = None
    rating_after: Optional[int] = None
    rating_change: Optional[int] = None


class GameOutcomeResponse(BaseModel):
    """Game outcome response."""
    id: int
    user_id: int
    game_uuid: str
    outcome: str
    opponent_id: Optional[int]
    format: Optional[str]
    rating_before: Optional[int]
    rating_after: Optional[int]
    rating_change: Optional[int]
    created_at: datetime
    
    model_config = ConfigDict(from_attributes=True)


class GameOutcomeListResponse(BaseModel):
    """List of game outcomes."""
    outcomes: List[GameOutcomeResponse]
    total: int


# ===== User Statistics Schemas =====

class UserStatisticsResponse(BaseModel):
    """User statistics summary response."""
    user_id: int
    total_games: int
    total_wins: int
    total_losses: int
    total_concessions: int
    win_rate: float
    current_streak: int
    best_streak: int
    average_rating: float
    last_game_date: Optional[datetime]
    updated_at: datetime
    
    model_config = ConfigDict(from_attributes=True)


class StatisticsUpdateResponse(BaseModel):
    """Response after updating statistics."""
    user_id: int
    total_games: int
    total_wins: int
    total_losses: int
    win_rate: float
    current_streak: int
    updated_at: datetime


# ===== Card Collection Schemas (moved to user_card_collection.py) =====
# These are kept here for backward compatibility but should be imported from user_card_collection.py


# ===== Wishlist Schemas (moved to user_card_collection.py) =====
# These are kept here for backward compatibility but should be imported from user_card_collection.py


# ===== Group Schemas =====

class GroupCreate(BaseModel):
    """User group creation request."""
    name: str = Field(..., min_length=1, max_length=100)
    description: Optional[str] = None
    is_public: bool = True
    max_members: int = Field(50, ge=2, le=500)


class GroupUpdate(BaseModel):
    """User group update request."""
    name: Optional[str] = None
    description: Optional[str] = None
    is_public: Optional[bool] = None
    max_members: Optional[int] = None


class GroupMemberCreate(BaseModel):
    """Group member addition request."""
    user_id: int
    role: GroupMemberRole = GroupMemberRole.MEMBER


class GroupMemberUpdate(BaseModel):
    """Group member role update request."""
    role: GroupMemberRole


class GroupMemberRemove(BaseModel):
    """Group member removal request."""
    user_id: int


class GroupResponse(BaseModel):
    """User group response."""
    id: int
    name: str
    description: Optional[str]
    owner_id: int
    is_public: bool
    max_members: int
    created_at: datetime
    updated_at: datetime
    member_count: int = 0
    is_member: bool = False
    
    model_config = ConfigDict(from_attributes=True)


class GroupListResponse(BaseModel):
    """List of user groups."""
    groups: List[GroupResponse]
    total: int


class GroupChatMessageCreate(BaseModel):
    """Group chat message creation request."""
    message: str = Field(..., min_length=1, max_length=2000)


class GroupChatMessageResponse(BaseModel):
    """Group chat message response."""
    id: int
    group_id: int
    sender_id: int
    sender_username: Optional[str] = None
    message: str
    created_at: datetime
    
    model_config = ConfigDict(from_attributes=True)


class GroupChatMessageListResponse(BaseModel):
    """List of group chat messages."""
    messages: List[GroupChatMessageResponse]
    total: int
    page: int
    page_size: int
    total_pages: int


# ===== Network Schemas =====

class NetworkCreate(BaseModel):
    """User network creation request."""
    name: str = Field(..., min_length=1, max_length=100)
    description: Optional[str] = None
    is_public: bool = True


class NetworkUpdate(BaseModel):
    """User network update request."""
    name: Optional[str] = None
    description: Optional[str] = None
    is_public: Optional[bool] = None


class NetworkMemberCreate(BaseModel):
    """Network member addition request."""
    user_id: int
    role: NetworkMemberRole = NetworkMemberRole.MEMBER


class NetworkResponse(BaseModel):
    """User network response."""
    id: int
    name: str
    description: Optional[str]
    creator_id: int
    is_public: bool
    created_at: datetime
    member_count: int = 0
    is_member: bool = False
    
    model_config = ConfigDict(from_attributes=True)


class NetworkListResponse(BaseModel):
    """List of user networks."""
    networks: List[NetworkResponse]
    total: int


# ===== Preference Schemas =====

class UserPreferenceUpdate(BaseModel):
    """User preference update request."""
    theme: Optional[UserPreferenceTheme] = None
    notifications_enabled: Optional[bool] = None
    email_notifications: Optional[bool] = None
    auto_save_decks: Optional[bool] = None
    default_format: Optional[str] = None
    language: Optional[str] = None


class UserPreferenceResponse(BaseModel):
    """User preference response."""
    user_id: int
    theme: str
    notifications_enabled: bool
    email_notifications: bool
    auto_save_decks: bool
    default_format: str
    language: str
    updated_at: datetime
    
    model_config = ConfigDict(from_attributes=True)


# ===== Activity Log Schemas =====

class ActivityLogEntry(BaseModel):
    """Activity log entry."""
    id: int
    user_id: int
    activity_type: str
    activity_data: Optional[Dict[str, Any]]
    ip_address: Optional[str]
    created_at: datetime
    
    model_config = ConfigDict(from_attributes=True)


class ActivityLogListResponse(BaseModel):
    """List of activity log entries."""
    entries: List[ActivityLogEntry]
    total: int
    page: int
    page_size: int
    total_pages: int


# ===== Generic Response Schemas =====

class MessageResponse(BaseModel):
    """Generic message response."""
    message: str


class CountResponse(BaseModel):
    """Generic count response."""
    count: int


class ErrorDetail(BaseModel):
    """Error detail."""
    error: str
    detail: str
