# @File: backend/schemas/mfa.py
# @Desc: Pydantic schemas for MFA endpoints.
from __future__ import annotations

from typing import Optional

from pydantic import BaseModel, Field


def _mask_phone(phone: Optional[str]) -> Optional[str]:
    """Return a masked representation of a phone number for display."""
    if not phone:
        return None
    if len(phone) <= 4:
        return "•" * len(phone)
    return f"{phone[:3]}•••{phone[-2:]}"


class MfaStatusResponse(BaseModel):
    """Current MFA state for the logged-in user."""

    enabled: bool
    method: str = "sms"
    phone_masked: Optional[str] = None
    last_verified_at: Optional[str] = None


class MfaAdminEnforceResponse(BaseModel):
    """Global admin-MFA enforcement flag."""

    require_admin_mfa: bool


class MfaAdminEnforceUpdate(BaseModel):
    require_admin_mfa: bool


class MfaSetupRequest(BaseModel):
    """Enroll a phone number for SMS MFA."""

    phone_e164: str = Field(..., min_length=5, max_length=32)


class MfaVerifySetupRequest(BaseModel):
    """Confirm the enrollment SMS code."""

    code: str = Field(..., min_length=4, max_length=10)


class MfaDisableRequest(BaseModel):
    """Disable MFA. Require the current account password as a safety check."""

    password: str = Field(..., min_length=1, max_length=256)


class MfaChallengeSendRequest(BaseModel):
    """Resend the login OTP during the MFA challenge step."""

    mfa_token: str


class MfaChallengeVerifyRequest(BaseModel):
    """Exchange an OTP + mfa_token for a real session JWT."""

    mfa_token: str
    code: str = Field(..., min_length=4, max_length=10)


class MfaGenericResponse(BaseModel):
    ok: bool
    message: str


class MfaSetupResponse(BaseModel):
    """Response to `/setup` — tells the UI that an SMS was dispatched."""

    ok: bool
    message: str
    phone_masked: Optional[str] = None
    expires_in_seconds: int = 600


class MfaAdminRosterEntry(BaseModel):
    """One row in the admin-side MFA roster."""

    user_id: str
    email: str
    name: Optional[str] = None
    enabled: bool
    phone_masked: Optional[str] = None
    last_verified_at: Optional[str] = None