"""Data Transfer Objects for gnexus-gauth."""

from dataclasses import dataclass, field
from datetime import datetime
from typing import Any


@dataclass(frozen=True)
class TokenSet:
    """OAuth token response."""

    access_token: str
    refresh_token: str | None
    token_type: str
    expires_in: int
    expires_at: datetime | None = None
    refresh_expires_in: int | None = None
    scopes: list[str] = field(default_factory=list)
    raw_payload: dict[str, Any] = field(default_factory=dict, repr=False)


@dataclass(frozen=True)
class ClientAccess:
    """Client-level access data for a user."""

    client_id: str
    access_status: str = "granted"
    role_ids: list[str] = field(default_factory=list)
    permission_ids: list[str] = field(default_factory=list)


@dataclass(frozen=True)
class AuthenticatedUser:
    """Normalized authenticated user payload from runtime API."""

    user_id: str
    email: str
    email_verified: bool
    system_role: str | None = None
    status: str | None = None
    profile: dict[str, Any] = field(default_factory=dict)
    client_access_list: list[ClientAccess] = field(default_factory=list)
    raw_payload: dict[str, Any] = field(default_factory=dict, repr=False)


@dataclass(frozen=True)
class AuthorizationRequest:
    """Authorization URL request with PKCE parameters."""

    authorization_url: str
    state: str
    pkce_verifier: str
    pkce_challenge: str
    scopes: list[str] = field(default_factory=list)
    return_to: str | None = None


@dataclass(frozen=True)
class VerifiedWebhook:
    """Result of successful webhook signature verification."""

    raw_body: str
    normalized_headers: dict[str, str]
    signature_id: str
    verified_at: datetime


@dataclass(frozen=True)
class WebhookEvent:
    """Parsed webhook event."""

    event_id: str | None
    event_type: str
    occurred_at: datetime | None = None
    target_identifiers: dict[str, Any] = field(default_factory=dict)
    actor_identifiers: dict[str, Any] = field(default_factory=dict)
    metadata: dict[str, Any] = field(default_factory=dict)
    raw_payload: dict[str, Any] = field(default_factory=dict, repr=False)
