from datetime import datetime
from typing import Protocol, TypeVar
from uuid import UUID

__all__ = [
    "RoleClaimProtokol",
    "RoleProtokol",
    "TKey",
    "TRole",
    "TRoleClaim",
    "TUser",
    "TUserClaim",
    "TUserLogin",
    "TUserRole",
    "TUserToken",
    "UserClaimProtokol",
    "UserLoginProtokol",
    "UserProtokol",
    "UserRoleProtokol",
    "UserTokenProtokol",
]

TKey = TypeVar("TKey", str, int, UUID)


class UserProtokol(Protocol[TKey]):
    access_failed_count: int
    concurrency_stamp: str | UUID | None
    email: str | None
    email_confirmed: bool
    id: TKey
    lockout_enabled: bool
    lockout_end: datetime | None
    normalized_email: str | None
    normalized_username: str | None
    password_hash: str | None
    phone_number: str | None
    phone_number_confirmed: bool
    security_stamp: str | UUID | None
    two_factor_enabled: bool
    username: str | None


class RoleProtokol(Protocol[TKey]):
    concurrency_stamp: str | UUID | None
    id: TKey
    name: str | None
    normalized_name: str | None


class UserRoleProtokol(Protocol[TKey]):
    user_id: TKey
    role_id: TKey


class UserClaimProtokol(Protocol[TKey]):
    claim_type: str | None
    claim_value: str | None
    user_id: TKey


class UserLoginProtokol(Protocol[TKey]):
    login_provider: str
    provider_key: str
    provider_display_name: str | None
    user_id: TKey


class UserTokenProtokol(Protocol[TKey]):
    login_provider: str
    name: str
    value: str | None
    user_id: TKey


class RoleClaimProtokol(Protocol[TKey]):
    claim_type: str | None
    claim_value: str | None
    role_id: TKey


TUser = TypeVar("TUser", bound=UserProtokol)  # type: ignore[type-arg]
TRole = TypeVar("TRole", bound=RoleProtokol)  # type: ignore[type-arg]
TUserRole = TypeVar("TUserRole", bound=UserRoleProtokol)  # type: ignore[type-arg]
TUserClaim = TypeVar("TUserClaim", bound=UserClaimProtokol)  # type: ignore[type-arg]
TUserLogin = TypeVar("TUserLogin", bound=UserLoginProtokol)  # type: ignore[type-arg]
TUserToken = TypeVar("TUserToken", bound=UserTokenProtokol)  # type: ignore[type-arg]
TRoleClaim = TypeVar("TRoleClaim", bound=RoleClaimProtokol)  # type: ignore[type-arg]
