"""
Type stubs for the built-in `gta` module.

The real `gta` module is a C extension baked into PyloaderV.asi and only
exists inside the GTA V process. These stubs let Pylance / mypy / IDE
autocomplete work when authoring .py scripts outside the game.

Point your Pylance at this folder via `pyrightconfig.json` (stubPath: "stubs").
"""

from typing import Any, Literal, NamedTuple, overload

from . import natives as natives
from . import entity as entity
from . import ped as ped
from . import vehicle as vehicle
from . import player as player
from . import world as world
from . import ui as ui
from . import math as math


__version__: str


# ---------------------------------------------------------------------------
# Vector3: what gta.invoke(..., return_type="vector3") returns.
#
# At runtime this is a collections.namedtuple("Vector3", "x y z"), so it's
# iterable, unpackable, and indexable like a tuple of 3 floats.
# ---------------------------------------------------------------------------
class Vector3(NamedTuple):
    x: float
    y: float
    z: float


# ---------------------------------------------------------------------------
# Native invocation
# ---------------------------------------------------------------------------
# `hash` : int OR "0x..." string
# `args` : int | float | bool | str | None | 3-tuple-of-floats (Vector3-like)
# `return_type` drives both what the stub says you get back AND what the C
# extension actually decodes from the native's 64-bit return slot.
# ---------------------------------------------------------------------------

@overload
def invoke(hash: int | str, *args: Any, return_type: Literal["int", "handle", "hash"] = "int") -> int: ...
@overload
def invoke(hash: int | str, *args: Any, return_type: Literal["uint", "ulong"]) -> int: ...
@overload
def invoke(hash: int | str, *args: Any, return_type: Literal["float"]) -> float: ...
@overload
def invoke(hash: int | str, *args: Any, return_type: Literal["bool"]) -> bool: ...
@overload
def invoke(hash: int | str, *args: Any, return_type: Literal["str"]) -> str | None: ...
@overload
def invoke(hash: int | str, *args: Any, return_type: Literal["vector3"]) -> Vector3: ...
@overload
def invoke(hash: int | str, *args: Any, return_type: Literal["void"]) -> None: ...


# ---------------------------------------------------------------------------
# Scheduling
# ---------------------------------------------------------------------------

def wait(ms: int = 0) -> None:
    """Yield this script's fiber until `ms` milliseconds have elapsed.

    ms=0 means "yield for one game tick". MUST be called from on_tick
    (or from a function called by it), NOT from on_key_down / on_start /
    on_aborted — those run on the main fiber and cannot yield.
    """
    ...


# ---------------------------------------------------------------------------
# Logging & UI
# ---------------------------------------------------------------------------

def log(level: Literal["debug", "info", "warn", "warning", "error"], message: str) -> None:
    """Write a line to PyloaderV.log."""
    ...


def notify(message: str) -> None:
    """Show a ticker notification in the top-left of the screen.

    Supports the usual GTA color codes: ~r~ red, ~g~ green, ~b~ blue,
    ~y~ yellow, ~w~ white, ~p~ purple, ~o~ orange, ~n~ newline.
    """
    ...


# ---------------------------------------------------------------------------
# World queries
# ---------------------------------------------------------------------------

def get_all_vehicles() -> list[int]:
    """Return handles of every Vehicle currently in the world."""
    ...


def get_all_peds() -> list[int]:
    """Return handles of every Ped currently in the world."""
    ...


def get_all_objects() -> list[int]:
    """Return handles of every Object currently in the world."""
    ...


def get_all_pickups() -> list[int]:
    """Return handles of every Pickup currently in the world."""
    ...


# ---------------------------------------------------------------------------
# Engine info
# ---------------------------------------------------------------------------

def game_version() -> int:
    """Return the eGameVersion enum value for the running build."""
    ...


# ---------------------------------------------------------------------------
# Low-level memory access — advanced users only.
# ---------------------------------------------------------------------------

def get_global_ptr(id: int) -> int:
    """Return a raw pointer (as int) to a script global."""
    ...


def entity_address(handle: int) -> int:
    """Return the base address of the native CEntity for a handle."""
    ...


def read_float(addr: int) -> float:
    """Read a float from a raw address. Raises OSError on access violation."""
    ...


def read_int(addr: int) -> int:
    """Read an int from a raw address. Raises OSError on access violation."""
    ...
