"""
Schema Pydantic per autenticazione e autorizzazione.
"""

import uuid
from datetime import datetime

from pydantic import BaseModel, EmailStr, Field, field_validator


# ─── Request ──────────────────────────────────────────────────────────────────

class LoginRequest(BaseModel):
    email: EmailStr
    password: str = Field(min_length=1)
    totp_code: str | None = Field(default=None, description="Codice TOTP 6 cifre (se 2FA attivo)")


class RefreshRequest(BaseModel):
    refresh_token: str


class TOTPVerifyRequest(BaseModel):
    totp_code: str = Field(min_length=6, max_length=6, description="Codice TOTP 6 cifre")


class PasswordChangeRequest(BaseModel):
    current_password: str
    new_password: str = Field(min_length=8)

    @field_validator("new_password")
    @classmethod
    def validate_password_strength(cls, v: str) -> str:
        if len(v) < 8:
            raise ValueError("La password deve essere almeno 8 caratteri")
        if not any(c.isupper() for c in v):
            raise ValueError("La password deve contenere almeno una lettera maiuscola")
        if not any(c.isdigit() for c in v):
            raise ValueError("La password deve contenere almeno un numero")
        return v


# ─── Response ─────────────────────────────────────────────────────────────────

class TokenResponse(BaseModel):
    access_token: str
    refresh_token: str
    token_type: str = "bearer"
    expires_in: int = Field(description="Scadenza access token in secondi")


class TOTPSetupResponse(BaseModel):
    """Dati per configurare TOTP sull'authenticator app."""
    secret: str = Field(description="Segreto TOTP base32 (da inserire manualmente)")
    qr_uri: str = Field(description="URI otpauth:// per il QR code")
    qr_image_base64: str = Field(description="QR code come immagine PNG base64")


class TOTPStatusResponse(BaseModel):
    totp_enabled: bool


class UserTokenData(BaseModel):
    """Dati estratti dal JWT per l'utente corrente."""
    user_id: uuid.UUID
    tenant_id: uuid.UUID
    role: str
    email: str | None = None
