from pydantic import BaseModel, EmailStr, Field, model_validator


class RegisterRequest(BaseModel):
    company_name: str = Field(min_length=2, max_length=255)
    first_name: str = Field(min_length=1, max_length=100)
    last_name: str = Field(min_length=1, max_length=100)
    email: EmailStr
    password: str = Field(min_length=8, max_length=128)

    @model_validator(mode="after")
    def password_strength(self):
        pw = self.password
        if not any(c.isupper() for c in pw):
            raise ValueError("Password must contain at least one uppercase letter")
        if not any(c.isdigit() for c in pw):
            raise ValueError("Password must contain at least one digit")
        return self


class LoginRequest(BaseModel):
    # Login-Kennung: i.d.R. eine E-Mail, kann aber auch eine intern erzeugte
    # Kennung sein (z.B. Mandanten-Admin ohne E-Mail → '<name>@<slug>.local').
    # Daher kein EmailStr-Zwang – das Passwort ist das eigentliche Gate.
    email: str = Field(min_length=1, max_length=255)
    password: str


class RefreshRequest(BaseModel):
    refresh_token: str | None = None


class PasswordResetRequest(BaseModel):
    email: EmailStr


class PasswordResetConfirm(BaseModel):
    token: str
    new_password: str = Field(min_length=8, max_length=128)

    @model_validator(mode="after")
    def password_strength(self):
        pw = self.new_password
        if not any(c.isupper() for c in pw):
            raise ValueError("Password must contain at least one uppercase letter")
        if not any(c.isdigit() for c in pw):
            raise ValueError("Password must contain at least one digit")
        return self


class TokenResponse(BaseModel):
    access_token: str
    refresh_token: str | None = None  # Nur für API-Clients; Browser nutzt HttpOnly-Cookie
    token_type: str = "bearer"
    totp_required: bool = False
    partial_token: str | None = None


class TotpSetupResponse(BaseModel):
    secret: str          # base32 secret for manual entry
    otpauth_uri: str     # otpauth://totp/... für QR-Code


class TotpConfirmRequest(BaseModel):
    code: str = Field(min_length=6, max_length=6)


class TotpLoginRequest(BaseModel):
    partial_token: str
    code: str = Field(min_length=6, max_length=6)


class TotpDisableRequest(BaseModel):
    password: str
    code: str = Field(min_length=6, max_length=6)


class AccessTokenResponse(BaseModel):
    access_token: str
    token_type: str = "bearer"


class MessageResponse(BaseModel):
    message: str
