from builtins import bool as py_bool
from typing import Any, Final, Literal as L, TypedDict, type_check_only

import numpy as np
from numpy import (
    bool,
    bool_,
    byte,
    bytes_,
    cdouble,
    character,
    clongdouble,
    complex64,
    complex128,
    complex192,
    complex256,
    complexfloating,
    csingle,
    datetime64,
    double,
    dtype,
    flexible,
    float16,
    float32,
    float64,
    float96,
    float128,
    floating,
    generic,
    half,
    inexact,
    int8,
    int16,
    int32,
    int64,
    int_,
    intc,
    integer,
    intp,
    long,
    longdouble,
    longlong,
    number,
    object_,
    short,
    signedinteger,
    single,
    str_,
    timedelta64,
    ubyte,
    uint,
    uint8,
    uint16,
    uint32,
    uint64,
    uintc,
    uintp,
    ulong,
    ulonglong,
    unsignedinteger,
    ushort,
    void,
)
from numpy._typing import DTypeLike

from ._type_aliases import sctypeDict as sctypeDict
from .multiarray import (
    busday_count,
    busday_offset,
    busdaycalendar,
    datetime_as_string,
    datetime_data,
    is_busday,
)

__all__ = [
    "ScalarType",
    "typecodes",
    "issubdtype",
    "datetime_data",
    "datetime_as_string",
    "busday_offset",
    "busday_count",
    "is_busday",
    "busdaycalendar",
    "isdtype",
    "generic",
    "unsignedinteger",
    "character",
    "inexact",
    "number",
    "integer",
    "flexible",
    "complexfloating",
    "signedinteger",
    "floating",
    "bool",
    "float16",
    "float32",
    "float64",
    "longdouble",
    "complex64",
    "complex128",
    "clongdouble",
    "bytes_",
    "str_",
    "void",
    "object_",
    "datetime64",
    "timedelta64",
    "int8",
    "byte",
    "uint8",
    "ubyte",
    "int16",
    "short",
    "uint16",
    "ushort",
    "int32",
    "intc",
    "uint32",
    "uintc",
    "int64",
    "long",
    "uint64",
    "ulong",
    "longlong",
    "ulonglong",
    "intp",
    "uintp",
    "double",
    "cdouble",
    "single",
    "csingle",
    "half",
    "bool_",
    "int_",
    "uint",
    "float96",
    "float128",
    "complex192",
    "complex256",
]

@type_check_only
class _TypeCodes(TypedDict):
    Character: L["c"]
    Integer: L["bhilqnp"]
    UnsignedInteger: L["BHILQNP"]
    Float: L["efdg"]
    Complex: L["FDG"]
    AllInteger: L["bBhHiIlLqQnNpP"]
    AllFloat: L["efdgFDG"]
    Datetime: L["Mm"]
    All: L["?bhilqnpBHILQNPefdgFDGSUVOMm"]

def isdtype(dtype: dtype | type, kind: DTypeLike | tuple[DTypeLike, ...]) -> py_bool: ...
def issubdtype(arg1: DTypeLike | None, arg2: DTypeLike | None) -> py_bool: ...

typecodes: Final[_TypeCodes] = ...
ScalarType: Final[
    tuple[
        type[int],
        type[float],
        type[complex],
        type[py_bool],
        type[bytes],
        type[str],
        type[memoryview[Any]],
        type[np.bool],
        type[complex64],
        type[complex128],
        type[complex128 | complex192 | complex256],
        type[float16],
        type[float32],
        type[float64],
        type[float64 | float96 | float128],
        type[int8],
        type[int16],
        type[int32],
        type[int32 | int64],
        type[int64],
        type[datetime64],
        type[timedelta64],
        type[object_],
        type[bytes_],
        type[str_],
        type[uint8],
        type[uint16],
        type[uint32],
        type[uint32 | uint64],
        type[uint64],
        type[void],
    ]
] = ...
typeDict: Final = sctypeDict
