from datetime import datetime
from typing import Literal, Optional
from uuid import UUID
import re
from pydantic import BaseModel, EmailStr, Field, field_validator


class UserBase(BaseModel):
    email: EmailStr
    name: str = Field(..., min_length=1, max_length=255)


class UserCreate(UserBase):
    password: str = Field(..., min_length=10, description="Password must be at least 10 characters")
    invite_code: Optional[str] = Field(None, description="Invite code for registration (required when invite system is enabled)")
    account_invite_code: Optional[str] = Field(None, description="Account invite code to join an existing account")

    @field_validator('password')
    @classmethod
    def password_complexity(cls, v: str) -> str:
        if not re.search(r'[A-Z]', v):
            raise ValueError('Password must contain at least one uppercase letter')
        if not re.search(r'[a-z]', v):
            raise ValueError('Password must contain at least one lowercase letter')
        if not re.search(r'[0-9]', v):
            raise ValueError('Password must contain at least one digit')
        return v


class UserUpdate(BaseModel):
    name: Optional[str] = Field(None, min_length=1, max_length=255)
    email: Optional[EmailStr] = None
    current_password: Optional[str] = Field(None, description="Required when changing email")
    phone: Optional[str] = Field(None, max_length=50)
    job_title: Optional[str] = Field(None, max_length=255)
    timezone: Optional[str] = Field(None, max_length=100)


class UserLogin(BaseModel):
    email: EmailStr
    password: str


class UserResponse(UserBase):
    id: UUID
    role: str = "engineer"
    account_id: Optional[UUID] = None
    account_role: Optional[str] = None
    is_super_admin: bool = False
    is_active: bool = True
    must_change_password: bool = False
    created_at: datetime
    last_login: Optional[datetime] = None
    deleted_at: Optional[datetime] = None
    phone: Optional[str] = None
    job_title: Optional[str] = None
    timezone: str = "UTC"
    avatar_url: Optional[str] = None
    email_verified_at: Optional[datetime] = None

    class Config:
        from_attributes = True


class RoleUpdate(BaseModel):
    role: Literal["engineer", "viewer"]


class AccountRoleUpdate(BaseModel):
    account_role: str = Field(..., pattern="^(engineer|viewer)$")
