from datetime import datetime
from pydantic import BaseModel, Field
from typing import Literal

from app.models.event import EventType
from app.schemas.user import UserPublic


# Event type literals for Pydantic
EventTypeLiteral = Literal[
    "golden_hour",
    "common_enemy",
    "double_risk",
    "jackpot",
    "swap",
    "game_choice",
]


class EventCreate(BaseModel):
    type: EventTypeLiteral
    duration_minutes: int | None = Field(
        None,
        description="Duration in minutes. If not provided, uses default for event type."
    )
    challenge_id: int | None = Field(
        None,
        description="For common_enemy event - the challenge everyone will get"
    )


class EventEffects(BaseModel):
    points_multiplier: float = 1.0
    drop_free: bool = False
    special_action: str | None = None  # "swap", "game_choice"
    description: str = ""


class EventResponse(BaseModel):
    id: int
    type: EventTypeLiteral
    start_time: datetime
    end_time: datetime | None
    is_active: bool
    created_by: UserPublic | None
    data: dict | None
    created_at: datetime

    class Config:
        from_attributes = True


class ActiveEventResponse(BaseModel):
    event: EventResponse | None
    effects: EventEffects
    time_remaining_seconds: int | None = None


class SwapRequest(BaseModel):
    target_participant_id: int


class CommonEnemyLeaderboard(BaseModel):
    participant_id: int
    user: UserPublic
    completed_at: datetime | None
    rank: int | None
    bonus_points: int


# Event descriptions and default durations
EVENT_INFO = {
    EventType.GOLDEN_HOUR: {
        "name": "Золотой час",
        "description": "Все очки x1.5!",
        "default_duration": 45,
        "points_multiplier": 1.5,
        "drop_free": False,
    },
    EventType.COMMON_ENEMY: {
        "name": "Общий враг",
        "description": "Все получают одинаковый челлендж. Первые 3 получают бонус!",
        "default_duration": None,  # Until all complete
        "points_multiplier": 1.0,
        "drop_free": False,
    },
    EventType.DOUBLE_RISK: {
        "name": "Безопасная игра",
        "description": "Дропы бесплатны, но очки x0.5",
        "default_duration": 120,
        "points_multiplier": 0.5,
        "drop_free": True,
    },
    EventType.JACKPOT: {
        "name": "Джекпот",
        "description": "Следующий спин — сложный челлендж с x3 очками!",
        "default_duration": None,  # 1 spin
        "points_multiplier": 3.0,
        "drop_free": False,
    },
    EventType.SWAP: {
        "name": "Обмен",
        "description": "Можно поменяться заданием с другим участником",
        "default_duration": 60,
        "points_multiplier": 1.0,
        "drop_free": False,
        "special_action": "swap",
    },
    EventType.GAME_CHOICE: {
        "name": "Выбор игры",
        "description": "Выбери игру и один из 3 челленджей. Можно заменить текущее задание без штрафа!",
        "default_duration": 120,
        "points_multiplier": 1.0,
        "drop_free": True,  # Free replacement of current assignment
        "special_action": "game_choice",
    },
}

# Bonus points for Common Enemy top 3
COMMON_ENEMY_BONUSES = {
    1: 50,
    2: 30,
    3: 15,
}


class SwapCandidate(BaseModel):
    """Participant available for assignment swap"""
    participant_id: int
    user: UserPublic
    is_playthrough: bool = False
    # Challenge fields (used when is_playthrough=False)
    challenge_title: str | None = None
    challenge_description: str | None = None
    challenge_points: int | None = None
    challenge_difficulty: str | None = None
    # Playthrough fields (used when is_playthrough=True)
    playthrough_description: str | None = None
    playthrough_points: int | None = None
    # Common field
    game_title: str


# Two-sided swap confirmation schemas
SwapRequestStatusLiteral = Literal["pending", "accepted", "declined", "cancelled"]


class SwapRequestCreate(BaseModel):
    """Request to swap assignment with another participant"""
    target_participant_id: int


class SwapRequestChallengeInfo(BaseModel):
    """Challenge or playthrough info for swap request display"""
    is_playthrough: bool = False
    # Challenge fields (used when is_playthrough=False)
    title: str | None = None
    description: str | None = None
    points: int | None = None
    difficulty: str | None = None
    # Playthrough fields (used when is_playthrough=True)
    playthrough_description: str | None = None
    playthrough_points: int | None = None
    # Common field
    game_title: str


class SwapRequestResponse(BaseModel):
    """Response for a swap request"""
    id: int
    status: SwapRequestStatusLiteral
    from_user: UserPublic
    to_user: UserPublic
    from_challenge: SwapRequestChallengeInfo
    to_challenge: SwapRequestChallengeInfo
    created_at: datetime
    responded_at: datetime | None

    class Config:
        from_attributes = True


class MySwapRequests(BaseModel):
    """User's incoming and outgoing swap requests"""
    incoming: list[SwapRequestResponse]
    outgoing: list[SwapRequestResponse]
