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


class UserCreate(BaseModel):
    username: str = Field(..., min_length=3, max_length=50, pattern=r'^[a-zA-Z0-9_-]+$')
    email: EmailStr
    password: str = Field(..., min_length=8, max_length=128)

    @field_validator('password')
    @classmethod
    def validate_password_strength(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 UserLogin(BaseModel):
    username: str = Field(..., min_length=3, max_length=50)
    password: str = Field(..., min_length=8, max_length=128)


class UserResponse(BaseModel):
    id: UUID
    username: str
    email: str
    created_at: datetime
    updated_at: datetime
    is_active: bool
    role_id: Optional[UUID] = None
    role_name: Optional[str] = None
    profile_image_url: Optional[str] = None
    twitch_id: Optional[str] = None
    twitch_username: Optional[str] = None
    is_twitch_linked: bool = False

    class Config:
        from_attributes = True

    @classmethod
    def from_orm_with_role(cls, user):
        """Create UserResponse with role_name from role relationship."""
        role_name = user.role.name if user.role else None
        return cls(
            id=user.id,
            username=user.username,
            email=user.email,
            created_at=user.created_at,
            updated_at=user.updated_at,
            is_active=user.is_active,
            role_id=user.role_id,
            role_name=role_name,
            profile_image_url=user.profile_image_url,
            twitch_id=user.twitch_id,
            twitch_username=user.twitch_username,
            is_twitch_linked=user.is_twitch_linked,
        )


class UserProfileUpdate(BaseModel):
    profile_image_url: Optional[str] = None


class Token(BaseModel):
    access_token: str
    refresh_token: str
    token_type: str = "bearer"
    user: UserResponse


class TokenRefresh(BaseModel):
    refresh_token: str
