from typing import Any, Awaitable, Callable, Optional
from enum import Enum
from bridge import ItemBuilder, BridgeCall
import asyncio


# ── NPC ──────────────────────────────────────────────────────────────
class NPC:
    def __init__(self, entity: Any, name: str | None = None) -> None: ...
    @classmethod
    async def spawn(cls, location: Any, entity_type: Any = "VILLAGER", name: str | None = None, **kwargs: Any) -> "NPC": ...
    @property
    def entity(self) -> Any: ...
    @property
    def uuid(self) -> str | None: ...
    @property
    def location(self) -> Any: ...
    def on_click(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def on_right_click(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def on_range_enter(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def on_range_exit(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def dialog(self, messages: list[str], loop: bool = False) -> None: ...
    async def move_to(self, location: Any, speed: float = 1.0) -> Any: ...
    async def follow_path(self, waypoints: list[Any], loop: bool = False, speed: float = 1.0, delay: float = 0.5) -> None: ...
    def stop_path(self) -> None: ...
    def link_dialog(self, dialog: "Dialog") -> None: ...
    def link_player(self, player: Any) -> None: ...
    def set_range(self, distance: float) -> None: ...
    async def remove(self) -> None: ...

# ── ImageDisplay ─────────────────────────────────────────────────────
class ImageDisplay:
    def __init__(self, location: Any, image: str | Any, pixel_size: float = ..., dual_sided: bool = False, dual_side_mode: str = "mirror") -> None: ...
    def teleport(self, location: Any) -> None: ...
    def remove(self) -> None: ...
    def update(self, image: str | Any) -> None: ...

# ── MeshDisplay ──────────────────────────────────────────────────────
class MeshDisplay:
    def __init__(self, location: Any, vertices: list[tuple[float, float, float]], faces: list[tuple[int, int, int]], face_colors: list[tuple[int, int, int, int]] | None = None, vertex_colors: list[tuple[int, int, int, int]] | None = None, texture: Any = None, uvs: list[tuple[float, float]] | None = None, face_uvs: list[tuple[int, int, int]] | None = None, pixel_size: float = ..., dual_sided: bool = False) -> None: ...
    def remove(self) -> None: ...
    def update(self, face_colors: list[tuple[int, int, int, int]] | None = None, vertex_colors: list[tuple[int, int, int, int]] | None = None) -> None: ...
    def update_geometry(self, vertices: list[tuple[float, float, float]], face_colors: list[tuple[int, int, int, int]] | None = None, vertex_colors: list[tuple[int, int, int, int]] | None = None) -> None: ...

# ── Quest ────────────────────────────────────────────────────────────
class Quest:
    name: str
    description: str
    time_limit: float | None
    def __init__(self, name: str, description: str = "", time_limit: float | None = None) -> None: ...
    def on_complete(self, func: Callable[..., Any]) -> Callable[..., Any]: ...
    def progress_getter(self, func: Callable[..., float]) -> Callable[..., float]: ...
    def status(self, player: Any) -> str: ...
    def progress(self, player: Any) -> float: ...
    def start_time(self, player: Any) -> float | None: ...
    def end_time(self, player: Any) -> float | None: ...
    def accept(self, player: Any) -> None: ...
    def start(self, player: Any) -> None: ...
    def complete(self, player: Any) -> None: ...
    def fail(self, player: Any) -> None: ...
    def end(self, player: Any) -> None: ...
    def show_bar(self, player: Any, color: str = "GREEN", style: str = "SEGMENTED_10") -> None: ...
    def hide_bar(self, player: Any) -> None: ...

class QuestTree:
    depth: int
    def __init__(self, tree: list[list[Quest] | Quest]) -> None: ...
    def current_depth(self, player: Any) -> int: ...
    def available(self, player: Any) -> list[Quest]: ...
    def active(self, player: Any) -> list[Quest]: ...
    def is_complete(self, player: Any) -> bool: ...
    def all_quests(self) -> list[Quest]: ...

# ── Dialog ───────────────────────────────────────────────────────────
class DialogEntry:
    speaker: str
    text: str
    answers: list[tuple[str, "DialogEntry | Callable[..., Any]"]]
    delay: float | None
    def __init__(self, speaker: str, text: str, answers: list[tuple[str, "DialogEntry | Callable[..., Any]"]] | None = None, delay: float | None = None) -> None: ...

class Dialog:
    def __init__(self, root: DialogEntry) -> None: ...
    def start(self, player: Any) -> None: ...
    def stop(self, player: Any) -> None: ...
    def is_active(self, player: Any) -> bool: ...

# ── Bank ─────────────────────────────────────────────────────────────
class Bank:
    name: str
    currency: str
    def __init__(self, name: str = "default", currency: str = "coins") -> None: ...
    def on_transaction(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def balance(self, player: Any) -> int: ...
    def deposit(self, player: Any, amount: int) -> None: ...
    def withdraw(self, player: Any, amount: int) -> bool: ...
    def transfer(self, source: Any, target: Any, amount: int) -> bool: ...
    def set_balance(self, player: Any, amount: int) -> None: ...
    @classmethod
    def get(cls, name: str = "default") -> "Bank | None": ...

# ── Shop ─────────────────────────────────────────────────────────────
class Shop:
    name: str
    items: list[tuple[Any, int]]
    def __init__(self, name: str = "Shop", bank: Bank | None = None, rows: int = 6) -> None: ...
    def on_purchase(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def add_item(self, item: Any, price: int) -> None: ...
    def remove_item(self, index: int) -> None: ...
    def open(self, player: Any, page: int = 0) -> None: ...
    def close(self, player: Any) -> None: ...

# ── TradeWindow ──────────────────────────────────────────────────────
class TradeWindow:
    def __init__(self, bank: Bank | None = None, delay: float = 3.0) -> None: ...
    def on_trade(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def open(self, p1: Any, p2: Any) -> None: ...
    def close(self, player: Any) -> None: ...

# ── Ability ──────────────────────────────────────────────────────────
class Ability:
    name: str
    description: str
    cooldown: float
    use_cost: float | None
    cooldown_msg: str
    display_bossbar: bool
    def __init__(self, name: str, description: str = "", cooldown: float = 1.0, use_cost: float | None = None, cooldown_msg: str = "§cAbility on cooldown! {remaining:.1f}s", display_bossbar: bool = False) -> None: ...
    def on_use(self, func: Callable[..., Any]) -> Callable[..., Any]: ...
    def can_use(self, func: Callable[..., bool]) -> Callable[..., bool]: ...
    def set_mana_store(self, mana_store: "ManaStore") -> None: ...
    def last_used(self, player: Any) -> float | None: ...
    def remaining_cooldown(self, player: Any) -> float: ...
    def use(self, player: Any) -> bool: ...

# ── ManaStore ────────────────────────────────────────────────────────
class ManaStore:
    default_mana: float
    default_max_mana: float
    default_regen_rate: float
    display_bossbar: bool
    def __init__(self, default_mana: float = 100.0, default_max_mana: float = 100.0, default_regen_rate: float = 1.0, display_bossbar: bool = False) -> None: ...
    def __getitem__(self, player: Any) -> float: ...
    def __setitem__(self, player: Any, value: float) -> None: ...
    def max_mana(self, player: Any) -> float: ...
    def set_max_mana(self, player: Any, value: float) -> None: ...
    def regen_rate(self, player: Any) -> float: ...
    def set_regen_rate(self, player: Any, value: float) -> None: ...
    def consume(self, player: Any, amount: float) -> bool: ...
    def restore(self, player: Any, amount: float) -> None: ...
    def start_regen(self) -> None: ...

# ── CombatSystem ─────────────────────────────────────────────────────
class CombatSystem:
    combat_timeout: float
    display_bossbar: bool
    def __init__(self, combat_timeout: float = 10.0, display_bossbar: bool = False) -> None: ...
    def on_combat_log(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def start(self) -> None: ...
    def in_combat(self, player: Any) -> bool: ...
    def in_combat_by_uuid(self, puuid: str) -> bool: ...
    def remaining(self, player: Any) -> float: ...

# ── LevelSystem ──────────────────────────────────────────────────────
class LevelSystem:
    multiplier: float
    exponent: float
    def __init__(self, multiplier: float = 100.0, exponent: float = 1.5, persist: bool = True, name: str = "levels") -> None: ...
    def __getitem__(self, player: Any) -> int: ...
    def on_level_up(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def xp_for_level(self, level: int) -> float: ...
    def level_from_xp(self, xp: float) -> int: ...
    def xp(self, player: Any) -> float: ...
    def level(self, player: Any) -> int: ...
    def add_xp(self, player: Any, amount: float) -> None: ...
    def set_xp(self, player: Any, value: float) -> None: ...
    def set_level(self, player: Any, level: int) -> None: ...
    def xp_to_next(self, player: Any) -> float: ...
    def progress(self, player: Any) -> float: ...

# ── Region ───────────────────────────────────────────────────────────
class Region:
    name: str
    x1: float
    y1: float
    z1: float
    x2: float
    y2: float
    z2: float
    def __init__(self, name: str, world: Any, x1: float, y1: float, z1: float, x2: float, y2: float, z2: float) -> None: ...
    @property
    def world(self) -> str: ...
    def on_enter(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def on_exit(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def contains(self, location: Any) -> bool: ...
    def is_inside(self, player: Any) -> bool: ...
    def remove(self) -> None: ...

# ── Party ────────────────────────────────────────────────────────────
class Party:
    name: str
    leader: Any
    members: list[Any]
    member_uuids: list[str]
    size: int
    def __init__(self, name: str, leader: Any, max_size: int = 4) -> None: ...
    def on_join(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def on_leave(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def on_disband(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def is_member(self, player: Any) -> bool: ...
    def is_leader(self, player: Any) -> bool: ...
    def join(self, player: Any) -> bool: ...
    def leave(self, player: Any) -> None: ...
    def kick(self, player: Any) -> None: ...
    def promote(self, player: Any) -> None: ...
    def disband(self) -> None: ...
    def broadcast(self, message: str) -> None: ...
    @classmethod
    def of(cls, player: Any) -> "Party | None": ...

# ── Guild ────────────────────────────────────────────────────────────
class Guild:
    name: str
    leader_uuid: str
    members: dict[str, str]
    size: int
    bank: Bank
    def __init__(self, name: str, leader: Any, max_size: int = 50, bank: Bank | None = None) -> None: ...
    def on_join(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def on_leave(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def on_disband(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def is_member(self, player: Any) -> bool: ...
    def rank(self, player: Any) -> str | None: ...
    def join(self, player: Any) -> bool: ...
    def leave(self, player: Any) -> None: ...
    def kick(self, player: Any) -> None: ...
    def promote(self, player: Any, rank: str = "officer") -> None: ...
    def demote(self, player: Any) -> None: ...
    def transfer_leadership(self, new_leader: Any) -> None: ...
    def disband(self) -> None: ...
    def broadcast(self, message: str) -> None: ...
    @classmethod
    def load(cls, name: str) -> "Guild | None": ...
    @classmethod
    def of(cls, player: Any) -> "Guild | None": ...
    @classmethod
    def get(cls, name: str) -> "Guild | None": ...

# ── CustomItem ───────────────────────────────────────────────────────
class CustomItem(ItemBuilder):
    item_id: str
    def __init__(self, item_id: str, material: str = "DIAMOND") -> None: ...
    def give(self, player: Any, amount: int = 1) -> None: ...
    @classmethod
    def get(cls, item_id: str) -> "CustomItem | None": ...
    @classmethod
    def all(cls) -> dict[str, "CustomItem"]: ...

# ── Leaderboard ──────────────────────────────────────────────────────
class Leaderboard:
    title: str
    update_interval: int
    max_entries: int
    def __init__(self, location: Any, title: str = "Leaderboard", get_metric: Callable[..., Any] | None = None, update_interval: int = 100, max_entries: int = 10) -> None: ...
    def metric(self, func: Callable[..., Any]) -> Callable[..., Any]: ...
    def start(self) -> None: ...
    def stop(self) -> None: ...

# ── VisualEffect ─────────────────────────────────────────────────────
class VisualEffect:
    name: str
    def __init__(self, name: str = "effect") -> None: ...
    def step(self, func: Callable[..., Any]) -> Callable[..., Any]: ...
    def add_step(self, func: Callable[..., Any]) -> None: ...
    async def trigger(self, location: Any) -> None: ...

# ── PlayerDataStore ──────────────────────────────────────────────────
class _PlayerView:
    def __getitem__(self, field: str) -> Any: ...
    def __setitem__(self, field: str, value: Any) -> None: ...
    def __delitem__(self, field: str) -> None: ...
    def __contains__(self, field: str) -> bool: ...
    def get(self, field: str, default: Any = None) -> Any: ...

class PlayerDataStore:
    name: str
    def __init__(self, name: str = "default") -> None: ...
    def __getitem__(self, player: Any) -> _PlayerView: ...
    def __setitem__(self, player: Any, value: dict[str, Any]) -> None: ...
    def get(self, player: Any, field: str, default: Any = None) -> Any: ...
    def set(self, player: Any, field: str, value: Any) -> None: ...
    def delete(self, player: Any, field: str | None = None) -> None: ...
    def all_data(self, player: Any) -> dict[str, Any]: ...

# ── Dungeon ──────────────────────────────────────────────────────────
class Exit:
    x: int
    y: int
    z: int
    facing: tuple[int, int, int]
    width: int
    height: int
    tag: str
    def __init__(self, x: int, y: int, z: int, facing: tuple[int, int, int], width: int, height: int, tag: str | None = None) -> None: ...
    def can_connect(self, other: "Exit") -> bool: ...

class RoomTemplate:
    name: str
    path: str
    type: str
    exits: list[Exit]
    weight: int
    loot: dict[str, str]
    key_map: dict[str, str]
    width: int
    height: int
    depth: int
    blocks: list[list[list[str]]]
    spawns: list[dict[str, Any]]
    @classmethod
    def load(cls, path: str) -> "RoomTemplate": ...
    def to_droom(self) -> str: ...
    def transformed(self, transform: str) -> "RoomTemplate": ...

class PlacedRoom:
    template: RoomTemplate
    origin: tuple[int, int, int]
    world_name: str
    connected_exits: dict[int, "PlacedRoom | None"]
    cleared: bool
    original_blocks: dict[tuple[int, int, int], str]
    aabb: tuple[tuple[int, int, int], tuple[int, int, int]]
    center: tuple[int, int, int]
    def on_enter(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def on_clear(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def mark_cleared(self) -> None: ...
    def paste(self, world: Any) -> BridgeCall: ...
    def restore(self, world: Any) -> BridgeCall: ...

def loot_pool(name: str) -> Callable[..., Any]: ...

class DungeonInstance:
    dungeon: "Dungeon"
    players: list[Any]
    instance_id: int
    rooms: list[PlacedRoom]
    world_name: str
    progress: float
    is_complete: bool
    def paste_all(self) -> BridgeCall: ...
    def complete(self) -> BridgeCall: ...
    def destroy(self) -> BridgeCall: ...
    def start_tracking(self) -> None: ...

class Dungeon:
    name: str
    rooms_dir: str
    room_count: int
    branch_factor: float
    min_candidates: int
    description: str
    difficulty: int
    start_room_name: str | None
    type_limits: dict[str, int]
    templates: list[RoomTemplate]
    instances: list[DungeonInstance]
    def __init__(self, name: str, rooms_dir: str, room_count: int = 12, branch_factor: float = 0.5, min_candidates: int = 5, description: str = "", difficulty: int = 1, start_room: str | None = None) -> None: ...
    def reload_templates(self) -> None: ...
    def add_template(self, template: RoomTemplate) -> None: ...
    def on_enter(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def on_complete(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def on_room_enter(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def on_room_clear(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def on_room_generate(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    def reward(self, handler: Callable[..., Any]) -> Callable[..., Any]: ...
    async def create_instance(self, players: list[Any], origin: tuple[int, int, int], world: Any = "world", room_count: int | None = None, branch_factor: float | None = None) -> DungeonInstance: ...

# ── Dungeon Transforms ───────────────────────────────────────────────
TRANSFORM_NONE: str
TRANSFORM_CW_90: str
TRANSFORM_CW_180: str
TRANSFORM_CW_270: str
TRANSFORM_MIRROR_X: str
TRANSFORM_MIRROR_Z: str
ALL_TRANSFORMS: list[str]

# ── TabList ──────────────────────────────────────────────────────────

class TabEntry:
    name: str
    ping: int
    skin: str | None
    game_mode: str
    def __init__(self, name: str, ping: int = 0, skin: str | None = None, game_mode: str = "SURVIVAL") -> None: ...

class TabGroup:
    name: str
    prefix: str
    priority: int
    def __init__(self, name: str, prefix: str = "", priority: int = 0) -> None: ...
    @property
    def entries(self) -> list[TabEntry]: ...
    def add_entry(self, entry: TabEntry) -> None: ...
    def remove_entry(self, name: str) -> None: ...

class TabList:
    def __init__(self) -> None: ...
    @property
    def header(self) -> str: ...
    @header.setter
    def header(self, value: str) -> None: ...
    @property
    def footer(self) -> str: ...
    @footer.setter
    def footer(self, value: str) -> None: ...
    def create_group(self, name: str, prefix: str = "", priority: int = 0) -> TabGroup: ...
    def get_group(self, name: str) -> TabGroup | None: ...
    def remove_group(self, name: str) -> None: ...
    def template(self, name: str) -> Callable[..., Callable[..., str]]: ...
    async def apply(self, player: Any) -> None: ...
    async def apply_all(self) -> None: ...
    def auto_update(self, interval_ticks: int = 20) -> asyncio.Task: ...

# ── StateMachine ─────────────────────────────────────────────────────

class SMState:
    name: str
    def __init__(self, name: str) -> None: ...
    def on_enter(self, func: Callable[..., Any]) -> Callable[..., Any]: ...
    def on_exit(self, func: Callable[..., Any]) -> Callable[..., Any]: ...
    def on_tick(self, func: Callable[..., Any]) -> Callable[..., Any]: ...
    def transition(self, event: str, target: str) -> None: ...

class StateMachine:
    name: str
    def __init__(self, name: str = "state_machine") -> None: ...
    @property
    def initial_state(self) -> str | None: ...
    @initial_state.setter
    def initial_state(self, value: str) -> None: ...
    def add_state(self, name: str) -> SMState: ...
    def get_state(self, name: str) -> SMState | None: ...
    def current_state(self, entity: Any) -> str | None: ...
    def attach(self, entity: Any) -> None: ...
    def detach(self, entity: Any) -> None: ...
    async def trigger(self, entity: Any, event: str) -> bool: ...
    async def force_state(self, entity: Any, state_name: str) -> None: ...
    def start_ticking(self, interval_ticks: int = 1, entity_resolver: Callable[..., Any] | None = None) -> asyncio.Task: ...
    def stop_ticking(self) -> None: ...

# ── Scheduler ────────────────────────────────────────────────────────

class ScheduledTask:
    name: str
    handler: Callable[..., Any]
    interval: float
    delay: float
    repeat: bool
    def __init__(self, name: str, handler: Callable[..., Any], interval: float = 0, delay: float = 0, repeat: bool = True) -> None: ...
    @property
    def cancelled(self) -> bool: ...
    @property
    def run_count(self) -> int: ...
    @property
    def last_run(self) -> float | None: ...
    def cancel(self) -> None: ...

class Scheduler:
    def __init__(self) -> None: ...
    @property
    def tasks(self) -> dict[str, ScheduledTask]: ...
    def every(self, seconds: float, name: str | None = None, delay: float = 0) -> Callable[..., Callable[..., Any]]: ...
    def after(self, seconds: float, name: str | None = None) -> Callable[..., Callable[..., Any]]: ...
    def schedule(self, name: str, handler: Callable[..., Any], interval: float = 0, delay: float = 0, repeat: bool = True) -> ScheduledTask: ...
    def cancel(self, name: str) -> None: ...
    def cancel_all(self) -> None: ...
    def start(self) -> None: ...
    def stop(self) -> None: ...

# ── PlaceholderRegistry ──────────────────────────────────────────────

class PlaceholderRegistry:
    def __init__(self) -> None: ...
    @property
    def names(self) -> list[str]: ...
    def register(self, name: str) -> Callable[..., Callable[..., str]]: ...
    def add(self, name: str, func: Callable[..., str]) -> None: ...
    def remove(self, name: str) -> None: ...
    def has(self, name: str) -> bool: ...
    def resolve(self, text: str, player: Any = None, **kwargs: Any) -> str: ...
    def resolve_many(self, texts: list[str], player: Any = None, **kwargs: Any) -> list[str]: ...

# ── LootTable ────────────────────────────────────────────────────────

class LootEntry:
    item: Any
    weight: int
    min_amount: int
    max_amount: int
    condition: Callable[..., bool] | None
    def __init__(self, item: Any, weight: int = 1, min_amount: int = 1, max_amount: int = 1, condition: Callable[..., bool] | None = None) -> None: ...

class LootPool:
    name: str
    rolls: int
    bonus_rolls: int
    def __init__(self, name: str = "pool", rolls: int = 1, bonus_rolls: int = 0) -> None: ...
    def add(self, item: Any, weight: int = 1, min_amount: int = 1, max_amount: int = 1, condition: Callable[..., bool] | None = None) -> LootEntry: ...
    def entry(self, item: Any, weight: int = 1, min_amount: int = 1, max_amount: int = 1, condition: Callable[..., bool] | None = None) -> Callable[..., Callable[..., bool]]: ...
    def generate(self, context: Any = None, luck: float = 0.0) -> list[dict]: ...

class LootTable:
    name: str
    def __init__(self, name: str = "loot_table") -> None: ...
    @property
    def pools(self) -> list[LootPool]: ...
    def add_pool(self, name: str = "pool", rolls: int = 1, bonus_rolls: int = 0) -> LootPool: ...
    def get_pool(self, name: str) -> LootPool | None: ...
    def remove_pool(self, name: str) -> None: ...
    def generate(self, context: Any = None, luck: float = 0.0) -> list[dict]: ...
    def generate_stacked(self, context: Any = None, luck: float = 0.0) -> list[dict]: ...



