from datetime import datetime
from typing import Literal, Optional

from pydantic import BaseModel, ConfigDict, EmailStr, Field
from pydantic.alias_generators import to_camel

LegChoice = Literal["full", "south", "central", "north"]
TshirtSize = Literal["S", "M", "L", "XL", "XXL"]


class CamelModel(BaseModel):
    """Base that accepts/serialises camelCase so it lines up with the React frontend."""

    model_config = ConfigDict(
        alias_generator=to_camel,
        populate_by_name=True,
        from_attributes=True,
    )


class RegistrationCreate(CamelModel):
    name: str = Field(min_length=1, max_length=120)
    email: EmailStr
    phone: str = Field(min_length=5, max_length=20)
    age: int = Field(ge=10, le=100)
    city: str = Field(min_length=1, max_length=120)
    blood_group: str = Field(max_length=8)
    experience: str = Field(max_length=40)
    weekly_km: int = Field(ge=0, le=2000)
    leg_choice: LegChoice
    needs_rental: bool = False
    tshirt_size: TshirtSize
    emergency_contact_name: str = Field(min_length=1, max_length=120)
    emergency_contact_phone: str = Field(min_length=5, max_length=20)
    medical_fitness_confirmed: bool


class RegistrationOut(RegistrationCreate):
    registration_id: str
    registered_at: datetime


class ContactCreate(CamelModel):
    name: str = Field(min_length=1, max_length=120)
    email: EmailStr
    phone: str = Field(min_length=5, max_length=20)
    message: Optional[str] = Field(default=None, max_length=4000)


class ContactOut(ContactCreate):
    id: int
    created_at: datetime


class SponsorshipCreate(CamelModel):
    company: str = Field(min_length=1, max_length=180)
    contact_name: str = Field(min_length=1, max_length=120)
    tier: str = Field(min_length=1, max_length=120)
    email: Optional[EmailStr] = None
    phone: Optional[str] = Field(default=None, max_length=20)
    message: Optional[str] = Field(default=None, max_length=4000)


class SponsorshipOut(SponsorshipCreate):
    id: int
    created_at: datetime


AdminRole = Literal["superadmin", "admin", "viewer"]


class AdminUserBase(CamelModel):
    email: EmailStr
    name: str = Field(min_length=1, max_length=120)
    role: AdminRole = "viewer"


class AdminUserCreate(AdminUserBase):
    password: str = Field(min_length=8, max_length=128)


class AdminUserUpdate(CamelModel):
    name: Optional[str] = Field(default=None, min_length=1, max_length=120)
    role: Optional[AdminRole] = None
    password: Optional[str] = Field(default=None, min_length=8, max_length=128)
    is_active: Optional[bool] = None


class AdminUserOut(AdminUserBase):
    id: int
    is_active: bool
    created_at: datetime


class Token(BaseModel):
    # snake_case on purpose — OAuth2 clients (incl. Swagger UI) expect these names.
    access_token: str
    token_type: str = "bearer"


class MediaAssetOut(CamelModel):
    id: int
    public_id: str
    secure_url: str
    title: Optional[str] = None
    category: str
    format: Optional[str] = None
    width: Optional[int] = None
    height: Optional[int] = None
    bytes: Optional[int] = None
    created_at: datetime
