from __future__ import annotations

from datetime import date, datetime, time
from typing import Any

from pydantic import BaseModel, Field


class ContestTemplateResponse(BaseModel):
    id: int
    name: str
    slug: str
    description: str | None = None
    prize_type: str
    prize_value: str
    max_winners: int
    attempts_per_user: int
    times_per_day: int
    schedule_times: str | None = None
    cooldown_hours: int
    payload: dict[str, Any] = Field(default_factory=dict)
    is_enabled: bool
    created_at: datetime
    updated_at: datetime


class ContestTemplateListResponse(BaseModel):
    items: list[ContestTemplateResponse]


class ContestTemplateUpdateRequest(BaseModel):
    name: str | None = None
    description: str | None = None
    prize_type: str | None = None
    prize_value: str | None = None
    max_winners: int | None = Field(None, ge=1)
    attempts_per_user: int | None = Field(None, ge=1)
    times_per_day: int | None = Field(None, ge=1)
    schedule_times: str | None = None
    cooldown_hours: int | None = Field(None, ge=1)
    payload: dict[str, Any] | None = None
    is_enabled: bool | None = None


class StartRoundRequest(BaseModel):
    starts_at: datetime | None = None
    ends_at: datetime | None = None
    cooldown_hours: int | None = Field(None, ge=1)
    payload: dict[str, Any] | None = None
    force: bool = False


class ContestRoundResponse(BaseModel):
    id: int
    template_id: int
    template_slug: str
    template_name: str | None = None
    starts_at: datetime
    ends_at: datetime
    status: str
    payload: dict[str, Any] = Field(default_factory=dict)
    winners_count: int
    max_winners: int
    attempts_per_user: int
    created_at: datetime
    updated_at: datetime


class ContestRoundListResponse(BaseModel):
    items: list[ContestRoundResponse]
    total: int
    limit: int
    offset: int


class ContestAttemptUser(BaseModel):
    id: int
    telegram_id: int | None = None
    username: str | None = None
    full_name: str | None = None


class ContestAttemptResponse(BaseModel):
    id: int
    round_id: int
    user: ContestAttemptUser
    answer: str | None = None
    is_winner: bool
    created_at: datetime


class ContestAttemptListResponse(BaseModel):
    items: list[ContestAttemptResponse]
    total: int
    limit: int
    offset: int


class ReferralContestResponse(BaseModel):
    id: int
    title: str
    description: str | None = None
    prize_text: str | None = None
    contest_type: str
    start_at: datetime
    end_at: datetime
    daily_summary_time: time
    daily_summary_times: str | None = None
    timezone: str
    is_active: bool
    last_daily_summary_date: date | None = None
    last_daily_summary_at: datetime | None = None
    final_summary_sent: bool
    created_by: int | None = None
    created_at: datetime
    updated_at: datetime


class ReferralContestListResponse(BaseModel):
    items: list[ReferralContestResponse]
    total: int
    limit: int
    offset: int


class ReferralContestCreateRequest(BaseModel):
    title: str
    description: str | None = None
    prize_text: str | None = None
    contest_type: str = Field('referral_paid', min_length=1)
    start_at: datetime
    end_at: datetime
    daily_summary_time: time = Field(default=time(hour=12))
    daily_summary_times: str | None = Field(
        default=None, description='Список времён ЧЧ:ММ через запятую (например, 12:00,18:00)'
    )
    timezone: str = Field(default='UTC')
    is_active: bool = True
    created_by: int | None = None


class ReferralContestUpdateRequest(BaseModel):
    title: str | None = None
    description: str | None = None
    prize_text: str | None = None
    contest_type: str | None = Field(None, min_length=1)
    start_at: datetime | None = None
    end_at: datetime | None = None
    daily_summary_time: time | None = None
    daily_summary_times: str | None = Field(default=None, description='Список времён ЧЧ:ММ через запятую')
    timezone: str | None = None
    is_active: bool | None = None
    final_summary_sent: bool | None = None
    created_by: int | None = None


class ReferralContestLeaderboardItem(BaseModel):
    user_id: int
    telegram_id: int | None = None
    username: str | None = None
    full_name: str | None = None
    referrals_count: int
    total_amount_kopeks: int
    total_amount_rubles: float


class ReferralContestDetailResponse(ReferralContestResponse):
    total_events: int | None = None
    leaderboard: list[ReferralContestLeaderboardItem] | None = None


class ReferralContestEventUser(BaseModel):
    id: int
    telegram_id: int | None = None
    username: str | None = None
    full_name: str | None = None


class ReferralContestEventResponse(BaseModel):
    id: int
    contest_id: int
    referrer: ReferralContestEventUser
    referral: ReferralContestEventUser
    event_type: str
    amount_kopeks: int
    amount_rubles: float
    occurred_at: datetime


class ReferralContestEventListResponse(BaseModel):
    items: list[ReferralContestEventResponse]
    total: int
    limit: int
    offset: int


class ReferralContestParticipant(BaseModel):
    referrer_id: int
    full_name: str
    total_referrals: int
    paid_referrals: int
    unpaid_referrals: int
    total_paid_amount: int


class ReferralContestDetailedStatsResponse(BaseModel):
    total_participants: int
    total_invited: int
    total_paid_amount: int
    total_unpaid: int
    participants: list[ReferralContestParticipant]
