# auth.py - Keep security-critical validation
import re
from datetime import datetime

from pydantic import BaseModel, ConfigDict, EmailStr, Field, field_validator


class UserLogin(BaseModel):
    email_or_username: str = Field(..., description="Username or email address")
    password: str = Field(..., description="Password")
    vendor_code: str | None = Field(
        None, description="Optional vendor code for context"
    )

    @field_validator("email_or_username")
    @classmethod
    def validate_email_or_username(cls, v):
        return v.strip()


class UserResponse(BaseModel):
    model_config = ConfigDict(from_attributes=True)
    id: int
    email: str
    username: str
    role: str
    is_active: bool
    last_login: datetime | None = None
    created_at: datetime
    updated_at: datetime


class LoginResponse(BaseModel):
    access_token: str
    token_type: str = "bearer"
    expires_in: int
    user: UserResponse


class UserDetailResponse(UserResponse):
    """Extended user response with additional details."""

    first_name: str | None = None
    last_name: str | None = None
    full_name: str | None = None
    is_email_verified: bool = False
    owned_companies_count: int = 0
    vendor_memberships_count: int = 0


class UserUpdate(BaseModel):
    """Schema for updating user information."""

    username: str | None = Field(None, min_length=3, max_length=50)
    email: EmailStr | None = None
    first_name: str | None = Field(None, max_length=100)
    last_name: str | None = Field(None, max_length=100)
    role: str | None = Field(None, pattern="^(admin|vendor)$")
    is_active: bool | None = None
    is_email_verified: bool | None = None

    @field_validator("username")
    @classmethod
    def validate_username(cls, v):
        if v and not re.match(r"^[a-zA-Z0-9_]+$", v):
            raise ValueError(
                "Username must contain only letters, numbers, or underscores"
            )
        return v.lower().strip() if v else v


class UserCreate(BaseModel):
    """Schema for creating a new user (admin only)."""

    email: EmailStr = Field(..., description="Valid email address")
    username: str = Field(..., min_length=3, max_length=50)
    password: str = Field(..., min_length=6, description="Password")
    first_name: str | None = Field(None, max_length=100)
    last_name: str | None = Field(None, max_length=100)
    role: str = Field(default="vendor", pattern="^(admin|vendor)$")

    @field_validator("username")
    @classmethod
    def validate_username(cls, v):
        if not re.match(r"^[a-zA-Z0-9_]+$", v):
            raise ValueError(
                "Username must contain only letters, numbers, or underscores"
            )
        return v.lower().strip()


class UserListResponse(BaseModel):
    """Schema for paginated user list."""

    items: list[UserResponse]
    total: int
    page: int
    per_page: int
    pages: int


class UserSearchItem(BaseModel):
    """Schema for a single user search result."""

    id: int
    username: str
    email: str
    is_active: bool


class UserSearchResponse(BaseModel):
    """Schema for user search results."""

    users: list[UserSearchItem]


class UserStatusToggleResponse(BaseModel):
    """Schema for user status toggle response."""

    message: str
    is_active: bool


class UserDeleteResponse(BaseModel):
    """Schema for user delete response."""

    message: str


class LogoutResponse(BaseModel):
    """Schema for logout response."""

    message: str


class PasswordResetRequestResponse(BaseModel):
    """Schema for password reset request response."""

    message: str


class PasswordResetResponse(BaseModel):
    """Schema for password reset response."""

    message: str


class VendorUserResponse(BaseModel):
    """Schema for vendor user info in auth context."""

    id: int
    username: str
    email: str
    role: str
    is_active: bool
