"""Pydantic request/response models for bincio.serve."""
from __future__ import annotations

from typing import Optional

from pydantic import BaseModel, Field


class LoginRequest(BaseModel):
    handle: str = Field(..., description="User handle (username)")
    password: str = Field(..., description="User password")


class LoginResponse(BaseModel):
    ok: bool = Field(True, description="Success flag")
    handle: str = Field(..., description="User handle")
    display_name: str = Field(..., description="User's display name")


class ResetPasswordRequest(BaseModel):
    handle: str = Field(..., description="User handle")
    code: str = Field(..., description="Reset code (24 hours valid)")
    password: str = Field(..., description="New password (min 8 chars)")


class RegisterRequest(BaseModel):
    code: str = Field(..., description="Invite code")
    handle: str = Field(..., description="Desired username (lowercase, 1-30 chars)")
    password: str = Field(..., description="Password (min 8 characters)")
    display_name: str = Field(default="", description="Full name (optional, defaults to handle)")


class RegisterResponse(BaseModel):
    ok: bool = Field(True, description="Success flag")
    handle: str = Field(..., description="New user's handle")


class CurrentUserResponse(BaseModel):
    handle: str = Field(..., description="User handle")
    display_name: str = Field(..., description="User's display name")
    is_admin: bool = Field(..., description="Whether user is an admin")
    wiki_access: bool = Field(default=True, description="Whether user has wiki access")
    activity_access: bool = Field(default=False, description="Whether user has activity access")
    store_originals_default: bool = Field(
        default=True,
        description="Instance-wide default for storing original files"
    )
    dem_configured: bool = Field(default=False, description="Whether DEM elevation lookup is configured")


class ActivityEditRequest(BaseModel):
    title: str | None = Field(default=None, description="Activity title")
    description: str | None = Field(default=None, description="Activity description (markdown)")
    sport: str | None = Field(default=None, description="Sport type")
    sub_sport: str | None = Field(default=None, description="Sport sub-category")
    private: bool | None = Field(default=None, description="Hide from public feed")
    highlight: bool | None = Field(default=None, description="Mark as favorite")
    gear: str | None = Field(default=None, description="Gear used")
    download_disabled: bool | None = Field(default=None, description="Prevent others from downloading files")


class ActivityEditResponse(BaseModel):
    ok: bool = Field(True, description="Success flag")


class ResetPasswordCodeResponse(BaseModel):
    ok: bool = Field(True, description="Success flag")
    code: str = Field(..., description="One-time reset code")
    expires_in_hours: int = Field(24, description="Code validity period in hours")


class GenericResponse(BaseModel):
    ok: bool = Field(True, description="Success flag")


class CreateSegmentRequest(BaseModel):
    name: str = Field(..., description="Segment name")
    sport: Optional[str] = Field(default=None, description="Sport filter")
    polyline: list[list[float]] = Field(..., description="[[lat, lon], ...] GPS points")
    distance_m: float = Field(..., description="Segment length in metres")


class CreateInviteRequest(BaseModel):
    grants_activity: bool = Field(default=False)


class IdeaBody(BaseModel):
    title: str
    body: str = ""


class IdeaCommentBody(BaseModel):
    comment: str = ""
