import abc
from abc import ABC, abstractmethod
from dataclasses import dataclass
from de.robv.android.xposed import XC_MethodHook as XC_MethodHook
from enum import Enum
from java.lang.reflect import Member as Member
from typing import Any, Callable, final

@dataclass
class PluginMetadata:
    id: str
    name: str
    description: str
    author: str
    version: str
    icon: str
    min_version: str

class HookStrategy(Enum):
    CANCEL = ...
    MODIFY = ...
    DEFAULT = ...
    MODIFY_FINAL = ...

@dataclass
class HookResult:
    strategy: HookStrategy = ...
    request: Any = ...
    response: Any = ...
    update: Any = ...
    updates: Any = ...
    error: Any = ...
    params: Any = ...

class PluginError(Exception):
    plugin_id: str | None
    def __init__(self, message: str, plugin_id: str | None = None) -> None: ...

class XposedHook(ABC): ...

class MethodReplacement(XposedHook, metaclass=abc.ABCMeta):
    @abstractmethod
    def replace_hooked_method(self, param: XC_MethodHook.MethodHookParam) -> Any: ...

class MethodHook(XposedHook):
    def before_hooked_method(self, param: XC_MethodHook.MethodHookParam): ...
    def after_hooked_method(self, param: XC_MethodHook.MethodHookParam): ...

class AppEvent(Enum):
    START = ...
    STOP = ...
    PAUSE = ...
    RESUME = ...

class MenuItemType(Enum):
    MESSAGE_CONTEXT_MENU = ...
    DRAWER_MENU = ...
    CHAT_ACTION_MENU = ...
    PROFILE_ACTION_MENU = ...

@dataclass
class MenuItemData:
    menu_type: MenuItemType
    text: str
    on_click: Callable[[dict[str, Any]], None]
    item_id: str | None = ...
    icon: str | None = ...
    subtext: str | None = ...
    condition: str | None = ...
    priority: int = ...

class BasePlugin:
    id: str
    name: str
    description: str
    author: str
    min_version: str
    version: str
    icon: str
    error_message: str
    enabled: bool
    initialized: bool
    def __init__(self) -> None: ...
    def on_plugin_load(self) -> None: ...
    def on_plugin_unload(self) -> None: ...
    def create_settings(self) -> list[Any]: ...
    def on_app_event(self, event_type: AppEvent): ...
    def pre_request_hook(self, request_name: str, account: int, request: Any) -> HookResult: ...
    def post_request_hook(self, request_name: str, account: int, response: Any, error: Any) -> HookResult: ...
    def on_update_hook(self, update_name: str, account: int, update: Any) -> HookResult: ...
    def on_updates_hook(self, container_name: str, account: int, updates: Any) -> HookResult: ...
    def on_send_message_hook(self, account: int, params: Any) -> HookResult: ...
    @final
    def add_hook(self, name: str, match_substring: bool = False, priority: int = 0): ...
    @final
    def add_on_send_message_hook(self, priority: int = 0): ...
    @final
    def remove_hook(self, name: str): ...
    @final
    def get_setting(self, key: str, default: Any = None) -> Any: ...
    @final
    def set_setting(self, key: str, value: Any): ...
    @final
    def hook_method(self, method_or_constructor: Member, xposed_hook: Any | None, priority: int | None = None) -> XC_MethodHook.Unhook | None: ...
    @final
    def unhook_method(self, unhook: XC_MethodHook.Unhook): ...
    @final
    def log(self, message: str): ...
    @final
    def add_menu_item(self, menu_item_data: MenuItemData) -> str | None: ...
    @final
    def remove_menu_item(self, item_id: str) -> bool: ...
