from pydantic import BaseModel, EmailStr, Field, validator
from typing import Optional
import re


class LoginRequest(BaseModel):
    email: EmailStr = Field(..., description="Email for authentication", example="admin@pige.com")
    password: str = Field(..., min_length=6, max_length=225, description="Password for authentication")


class EmailRequest(BaseModel):
    email: EmailStr = Field(..., description="The user's email address")


class RegisterRequest(BaseModel):
    company_name: Optional[str] = Field(None, description="User company name for registration", example="Company Pige")
    company_type: str = Field(..., description="User Company type for registration", example="Anonymous Company")
    username: Optional[str] = Field(None, description="Username for registration", example="admin@pige")
    email: EmailStr = Field(..., description="Email for registration", example="admin@pige.com")
    password: str = Field(..., min_length=8, description="Password for registration")
    password_confirm: str = Field(..., min_length=8, description="Password Confirmation for registration")

    @validator('company_type')
    def validate_company_type(cls, v):
        allowed_types = ["Anonymous Company", "Brands Company", "Ad Agency Company", "TV Channels Company"]
        if v not in allowed_types:
            raise ValueError('Invalid company type')
        return v

    @validator('password')
    def validate_password(cls, v):
        if len(v) < 8:
            raise ValueError('Password must be at least 8 characters')
        if not re.match(r"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$", v):
            raise ValueError('Password must contain at least one lowercase letter, one uppercase letter, and one digit')
        return v

    @validator('password_confirm')
    def passwords_match(cls, v, values, **kwargs):
        if 'password' in values and v != values['password']:
            raise ValueError('Passwords do not match')
        return v


class RefreshTokenRequest(BaseModel):
    refresh: str = Field(..., description="Refresh token for obtaining a new access token")


class TokenResponse(BaseModel):
    access: str
    refresh: str


class LoginResponse(BaseModel):
    msg: str
    user_id: str
    token: TokenResponse


class MessageResponse(BaseModel):
    msg: str


class ErrorResponse(BaseModel):
    error: str
    msg: str