"""
Authentication schema definitions for common operations.
"""

from datetime import datetime
from typing import Optional
from pydantic import EmailStr, Field, ConfigDict
from src.apps.base.schemas.common import BaseSchema


class AuthBase(BaseSchema):
    """Base authentication schema."""
    
    email: EmailStr = Field(..., description="User's email address")
    password: str = Field(..., min_length=8, description="User's password")


class LoginRequestSchema(AuthBase):
    """Schema for login request."""
    pass


class LoginResponseSchema(BaseSchema):
    """Schema for login response."""
    
    model_config = ConfigDict(from_attributes=True)
    
    message: str = Field(..., description="Authentication result message")
    user_id: int = Field(..., description="User's unique identifier")
    email: EmailStr = Field(..., description="User's email address")
    is_active: bool = Field(..., description="Whether the user is active")
    is_verified: bool = Field(..., description="Whether the user is verified")
    access_token: str = Field(..., description="JWT access token")
    refresh_token: str = Field(..., description="JWT refresh token")
    token_type: str = Field(default="bearer", description="Token type")
    expires_in: int = Field(..., description="Access token expiration time in seconds")


class RegisterRequestSchema(BaseSchema):
    """Schema for user registration."""
    
    email: EmailStr = Field(..., description="User's email address")
    password: str = Field(..., min_length=8, description="User's password")
    first_name: Optional[str] = Field(None, max_length=100, description="User's first name")
    middle_name: Optional[str] = Field(None, max_length=100, description="User's middle name")
    last_name: Optional[str] = Field(None, max_length=100, description="User's last name")
    phone: Optional[str] = Field(None, max_length=20, description="User's phone number")


class RegisterResponseSchema(BaseSchema):
    """Schema for registration response."""
    
    model_config = ConfigDict(from_attributes=True)
    
    message: str = Field(..., description="Registration result message")
    user_id: int = Field(..., description="User's unique identifier")
    email: EmailStr = Field(..., description="User's email address")
    is_active: bool = Field(..., description="Whether the user is active")
    is_verified: bool = Field(..., description="Whether the user is verified")


class AuthTokenSchema(BaseSchema):
    """Schema for authentication token."""
    
    access_token: str = Field(..., description="JWT access token")
    refresh_token: str = Field(..., description="JWT refresh token")
    token_type: str = Field(default="bearer", description="Token type")
    expires_in: int = Field(..., description="Token expiration time in seconds")


class RefreshTokenRequestSchema(BaseSchema):
    """Schema for token refresh request."""
    
    refresh_token: str = Field(..., description="JWT refresh token")


class LogoutResponseSchema(BaseSchema):
    """Schema for logout response."""
    
    message: str = Field(..., description="Logout result message")
    logged_out_sessions: int = Field(..., description="Number of sessions logged out")


class UserProfileSchema(BaseSchema):
    """Schema for user profile information in /me endpoint."""
    
    model_config = ConfigDict(from_attributes=True)
    
    id: int = Field(..., description="User's unique identifier")
    user_id: Optional[str] = Field(None, description="User's external identifier")
    email: EmailStr = Field(..., description="User's email address")
    username: Optional[str] = Field(None, description="User's username")
    first_name: Optional[str] = Field(None, description="User's first name")
    middle_name: Optional[str] = Field(None, description="User's middle name")
    last_name: Optional[str] = Field(None, description="User's last name")
    phone: Optional[str] = Field(None, description="User's phone number")
    is_active: bool = Field(..., description="Whether the user is active")
    is_verified: bool = Field(..., description="Whether the user is verified")
    is_superuser: bool = Field(..., description="Whether the user is a superuser")
    created_at: datetime = Field(..., description="When the user was created")
    updated_at: Optional[datetime] = Field(None, description="When the user was last updated")
    last_login: Optional[datetime] = Field(None, description="User's last login time")
    
    @property
    def full_name(self) -> str:
        """Get user's full name."""
        names = [name for name in [self.first_name, self.middle_name, self.last_name] if name]
        return " ".join(names) if names else ""


class PasswordResetRequestSchema(BaseSchema):
    """Schema for password reset request."""
    
    email: EmailStr = Field(..., description="User's email address")


class PasswordResetSchema(BaseSchema):
    """Schema for password reset."""
    
    token: str = Field(..., description="Password reset token")
    new_password: str = Field(..., min_length=8, description="New password")
    confirm_password: str = Field(..., min_length=8, description="Confirm new password")
