"""Authentication Pydantic schemas — inbound requests and outbound responses.

Uses repo_core base classes:
    - ``BaseRequestSchema`` — inbound (extra="forbid")
    - ``BaseResponseSchema`` — outbound (from_attributes=True)
"""

from __future__ import annotations

import uuid
from datetime import datetime

from pydantic import BaseModel, Field

from repo_core.base.schemas import BaseRequestSchema, BaseResponseSchema


# -- API Key Management ----------------------------------------------------

class ApiKeyCreateRequest(BaseRequestSchema):
    """Payload for creating a new API key."""
    name: str = Field(..., min_length=1, max_length=128)
    scopes: list[str] = Field(default_factory=list)


class ApiKeyResponse(BaseResponseSchema):
    """API key metadata returned to the caller (never includes the raw key)."""
    id: uuid.UUID
    name: str
    scopes: list[str] = Field(default_factory=list)
    is_active: bool = True
    created_at: datetime | None = None
    last_used_at: datetime | None = None


class ApiKeyCreatedResponse(BaseModel):
    """Returned once when an API key is created — includes the raw key value."""
    id: uuid.UUID
    name: str
    key: str  # raw key — only shown at creation time
    scopes: list[str] = Field(default_factory=list)
    created_at: datetime | None = None


class ApiKeyRevokeRequest(BaseRequestSchema):
    """Payload for revoking an API key."""
    reason: str | None = None


# -- Login / Token ---------------------------------------------------------

class LoginRequest(BaseRequestSchema):
    """Credentials for dashboard user login."""
    username: str = Field(..., min_length=1, max_length=64)
    password: str = Field(..., min_length=8, max_length=256)


class RegisterRequest(BaseRequestSchema):
    """Payload for registering a dashboard user."""
    username: str = Field(..., min_length=3, max_length=64)
    email: str = Field(..., min_length=5, max_length=254)
    password: str = Field(..., min_length=8, max_length=256)
    display_name: str | None = Field(default=None, max_length=128)
    role: str = Field(default="viewer", min_length=3, max_length=64)


class UserResponse(BaseResponseSchema):
    """Safe user profile response (no password hash)."""
    id: uuid.UUID
    username: str
    email: str
    display_name: str | None = None
    role: str = "user"
    is_active: bool = True
    created_at: datetime | None = None
    last_login_at: datetime | None = None


class ApiKeyLoginRequest(BaseRequestSchema):
    """Payload for exchanging an API key via auth endpoint."""
    api_key: str = Field(..., min_length=1)


class TokenResponse(BaseModel):
    """Access token returned on successful authentication."""
    access_token: str
    refresh_token: str | None = None
    token_type: str = "bearer"
    auth_type: str = "user"
    scopes: list[str] = Field(default_factory=list)
    expires_at: datetime | None = None
    refresh_expires_at: datetime | None = None


# -- Validation ------------------------------------------------------------

class ApiKeyValidationResult(BaseModel):
    """Result of validating an API key — used internally by middleware."""
    valid: bool
    api_key_id: uuid.UUID | None = None
    scopes: list[str] = Field(default_factory=list)
    error: str | None = None


class JwtValidationResult(BaseModel):
    """Result of validating a JWT bearer token."""
    valid: bool
    principal_id: str | None = None
    principal_type: str | None = None
    username: str | None = None
    scopes: list[str] = Field(default_factory=list)
    role: str | None = None
    error: str | None = None


class RoleResponse(BaseResponseSchema):
    """Role response schema."""
    id: uuid.UUID
    name: str
    description: str | None = None
    scopes: list[str] = Field(default_factory=list)
    is_active: bool = True
    created_at: datetime | None = None
