"""User management schemas for web API."""

from __future__ import annotations

from datetime import datetime
from typing import Optional

from pydantic import BaseModel, ConfigDict, EmailStr, Field

from backend.constants.roles import DEFAULT_USER_ROLE, UserRole


class UserResponse(BaseModel):
    """User DTO returned from API."""

    model_config = ConfigDict(from_attributes=True, protected_namespaces=())

    id: int
    username: str
    email: Optional[str] = None
    full_name: Optional[str] = None
    is_active: bool
    is_admin: bool
    role: UserRole
    password_change_required: bool
    created_date: datetime
    last_login: Optional[datetime] = None


class UserCreateRequest(BaseModel):
    """Request payload to create a new user."""

    model_config = ConfigDict(protected_namespaces=())

    username: str = Field(..., min_length=1, max_length=100)
    password: str = Field(..., min_length=6, description="Password (minimum 6 characters)")
    email: EmailStr = Field(..., description="Email address (required)")
    full_name: str = Field(..., min_length=1, max_length=200, description="Full name (required)")
    is_active: bool = True
    is_admin: bool = False
    role: UserRole = Field(
        DEFAULT_USER_ROLE,
        description="Role for feature-level access; also controls admin status where applicable",
    )
    give_frontend_permission: bool = Field(False, description="Create user in auth database for frontend access")


class UserUpdateRequest(BaseModel):
    """Request payload to update a user."""

    model_config = ConfigDict(protected_namespaces=())

    password: Optional[str] = Field(None, min_length=6, description="New password (minimum 6 characters, leave empty to keep current)")
    email: EmailStr = Field(..., description="Email address (required)")
    full_name: str = Field(..., min_length=1, max_length=200, description="Full name (required)")
    is_active: Optional[bool] = None
    is_admin: Optional[bool] = None
    role: Optional[UserRole] = Field(
        None,
        description="Updated role; determines admin status when provided",
    )
    give_frontend_permission: Optional[bool] = Field(
        None,
        description="Create user in auth database for frontend access if True",
    )


class UsersListResponse(BaseModel):
    """List of users."""

    model_config = ConfigDict(protected_namespaces=())

    items: list[UserResponse]
    total: int

