"""Base Entity wrapper (superclass of Ped, Vehicle, Object)."""

from __future__ import annotations

import gta
from gta.natives.entity import (
    DOES_ENTITY_EXIST,
    GET_ENTITY_COORDS,
    GET_ENTITY_HEADING,
    GET_ENTITY_HEALTH,
    IS_ENTITY_DEAD,
    SET_ENTITY_AS_NO_LONGER_NEEDED,
    SET_ENTITY_COORDS,
    SET_ENTITY_HEADING,
    SET_ENTITY_HEALTH,
    DELETE_ENTITY,
)


class Entity:
    __slots__ = ("handle",)

    def __init__(self, handle: int) -> None:
        self.handle = handle

    def __repr__(self) -> str:
        return f"{type(self).__name__}(handle={self.handle})"

    def __bool__(self) -> bool:
        return self.exists

    def __eq__(self, other: object) -> bool:
        return isinstance(other, Entity) and self.handle == other.handle

    def __hash__(self) -> int:
        return hash(("Entity", self.handle))

    @property
    def exists(self) -> bool:
        return self.handle != 0 and DOES_ENTITY_EXIST(self.handle)

    @property
    def position(self) -> "gta.Vector3":
        return GET_ENTITY_COORDS(self.handle, True)

    @position.setter
    def position(self, xyz: "gta.Vector3") -> None:
        x, y, z = xyz
        SET_ENTITY_COORDS(self.handle, x, y, z, False, False, False, True)

    @property
    def heading(self) -> float:
        return GET_ENTITY_HEADING(self.handle)

    @heading.setter
    def heading(self, value: float) -> None:
        SET_ENTITY_HEADING(self.handle, value)

    @property
    def health(self) -> int:
        return GET_ENTITY_HEALTH(self.handle)

    @health.setter
    def health(self, value: int) -> None:
        SET_ENTITY_HEALTH(self.handle, value, 0, 0)

    @property
    def is_dead(self) -> bool:
        return IS_ENTITY_DEAD(self.handle, False)

    def dismiss(self) -> None:
        """Mark as no-longer-needed so the engine can stream it out."""
        SET_ENTITY_AS_NO_LONGER_NEEDED(self.handle)

    def delete(self) -> None:
        """Force-delete immediately. Prefer `dismiss()` for natural despawn."""
        DELETE_ENTITY(self.handle)
