from dataclasses import dataclass
from datetime import datetime
from typing import NamedTuple, Optional, Sequence, TypeAlias, TypedDict, TYPE_CHECKING, Union
from unpoly.typehints import UnpolyHttpRequest
from uuid import UUID

if TYPE_CHECKING:
    from django.utils.functional import _StrPromise
    from sandbox.latchstring.models import User as UserType
else:
    from django.utils.functional import Promise as _StrPromise

StrOrPromise: TypeAlias = str | _StrPromise
PrimaryKey = Union[int, UUID]
OptionalPrimaryKey = Optional[PrimaryKey]
CanonicalID = UUID
CanonicalIDString = str
CanonicalIDOrString = str | CanonicalID
CanonicalIDs = list[CanonicalIDString]
FIELDS = tuple[str, ...]
SELECT_OBJECTS_TYPE = Sequence[tuple[StrOrPromise, StrOrPromise]]


@dataclass(slots=True, frozen=True)
class View:
    name: str
    icon: str
    url: str
    url_name: str


@dataclass(slots=True, frozen=True)
class Partition:
    name: str
    start_date: datetime | None
    end_date: datetime | None


class LookupField(NamedTuple):
    name: str
    required: bool


class Changes(NamedTuple):
    old: OptionalPrimaryKey
    new: OptionalPrimaryKey


class TenantChange(TypedDict):
    old: PrimaryKey | None
    new: PrimaryKey | None


FILTER_FIELDS = Sequence[Union[FIELDS, tuple[FIELDS, str]]]


class LCHttpRequest(UnpolyHttpRequest):
    """
    Add user properties to HttpRequest
    """

    user: 'UserType'
    impersonator: Optional['UserType']
    real_user: Optional['UserType']
