"""
User schemas
"""
from datetime import datetime
from typing import List, Optional
from uuid import UUID

from pydantic import BaseModel, EmailStr, Field, validator

from app.domain.entities.user import User, UserRole, UserStatus


class UserBase(BaseModel):
    """Base user schema"""
    email: EmailStr
    username: str = Field(..., min_length=3, max_length=50)
    first_name: str = Field(..., min_length=1, max_length=100)
    last_name: str = Field(..., min_length=1, max_length=100)
    phone_number: Optional[str] = None
    timezone: str = "UTC"
    language: str = "en"
    department: Optional[str] = None
    job_title: Optional[str] = None


class UserCreate(UserBase):
    """User creation schema"""
    password: str = Field(..., min_length=8)
    roles: List[UserRole] = Field(default_factory=lambda: [UserRole.USER])
    send_welcome_email: bool = True
    
    @validator("password")
    def validate_password(cls, v):
        if len(v) < 8:
            raise ValueError("Password must be at least 8 characters long")
        if not any(c.isupper() for c in v):
            raise ValueError("Password must contain at least one uppercase letter")
        if not any(c.islower() for c in v):
            raise ValueError("Password must contain at least one lowercase letter")
        if not any(c.isdigit() for c in v):
            raise ValueError("Password must contain at least one digit")
        return v


class UserUpdate(BaseModel):
    """User update schema"""
    first_name: Optional[str] = Field(None, min_length=1, max_length=100)
    last_name: Optional[str] = Field(None, min_length=1, max_length=100)
    phone_number: Optional[str] = None
    timezone: Optional[str] = None
    language: Optional[str] = None
    department: Optional[str] = None
    job_title: Optional[str] = None
    avatar_url: Optional[str] = None


class UserResponse(UserBase):
    """User response schema"""
    id: UUID
    status: UserStatus
    roles: List[UserRole]
    permissions: List[str]
    avatar_url: Optional[str] = None
    is_email_verified: bool
    is_2fa_enabled: bool
    created_at: datetime
    updated_at: datetime
    last_login_at: Optional[datetime] = None
    last_activity_at: Optional[datetime] = None
    organization_id: Optional[UUID] = None
    
    @classmethod
    def from_entity(cls, user: User) -> "UserResponse":
        """Create response from user entity"""
        return cls(
            id=user.id,
            email=user.email,
            username=user.username,
            first_name=user.first_name,
            last_name=user.last_name,
            phone_number=user.phone_number,
            timezone=user.timezone,
            language=user.language,
            department=user.department,
            job_title=user.job_title,
            status=user.status,
            roles=user.roles,
            permissions=user.permissions,
            avatar_url=user.avatar_url,
            is_email_verified=user.is_email_verified,
            is_2fa_enabled=user.is_2fa_enabled,
            created_at=user.created_at,
            updated_at=user.updated_at,
            last_login_at=user.last_login_at,
            last_activity_at=user.last_activity_at,
            organization_id=user.organization_id
        )


class UserListResponse(BaseModel):
    """User list response schema"""
    id: UUID
    email: EmailStr
    username: str
    first_name: str
    last_name: str
    status: UserStatus
    roles: List[UserRole]
    is_email_verified: bool
    created_at: datetime
    last_login_at: Optional[datetime] = None
    
    @classmethod
    def from_entity(cls, user: User) -> "UserListResponse":
        """Create list response from user entity"""
        return cls(
            id=user.id,
            email=user.email,
            username=user.username,
            first_name=user.first_name,
            last_name=user.last_name,
            status=user.status,
            roles=user.roles,
            is_email_verified=user.is_email_verified,
            created_at=user.created_at,
            last_login_at=user.last_login_at
        )


class UserStatusUpdate(BaseModel):
    """User status update schema"""
    status: UserStatus


class UserRoleUpdate(BaseModel):
    """User role update schema"""
    roles: List[UserRole]


class UserProfileUpdate(BaseModel):
    """User profile update schema"""
    first_name: Optional[str] = Field(None, min_length=1, max_length=100)
    last_name: Optional[str] = Field(None, min_length=1, max_length=100)
    phone_number: Optional[str] = None
    timezone: Optional[str] = None
    language: Optional[str] = None
    avatar_url: Optional[str] = None
