"""装饰器注册表。

核心思想：
    - 所有条件都是 Condition 实例或返回 Condition 的函数
    - 业务代码只关心“写在函数上的条件”，调度由 Bot 负责
"""

from __future__ import annotations

from typing import Callable, List

from .condition import (
    Condition,
    create_condition,
    message_type_is,
    raw_message_contains,
    user_id_in,
    group_id_in,
)


class EventHandler:
    """全局处理器注册表。"""

    def __init__(self) -> None:
        self._handlers: List[dict] = []

    def register_handler(self, func: Callable, condition: Condition | None = None) -> None:
        """注册处理器到适配器。"""
        self._handlers.append({"func": func, "condition": condition})

    def get_handlers(self) -> list[dict]:
        return list(self._handlers)

    def clear(self) -> None:
        """用于测试或重置。"""
        self._handlers.clear()


# 单例注册表
handler = EventHandler()


# ========== 单例条件：可直接 @condition ==========

# 无括号魔法：这些本身就是 Condition 实例
on_group_message = message_type_is("group")
on_private_message = message_type_is("private")
on_at_me = create_condition(
    lambda e: f"[CQ:at,qq={getattr(e, 'self_id', '')}]" in (getattr(e, "raw_message", "") or ""),
    name="is_at_me",
)


# ========== 参数化条件：函数返回 Condition ==========

def on_keyword(*keywords: str) -> Condition:
    """有参数，必须括号，但内部统一走工厂。"""
    return raw_message_contains(*keywords)


def from_user(user_ids: list[int]) -> Condition:
    return user_id_in(user_ids)


def from_group(group_ids: list[int]) -> Condition:
    return group_id_in(group_ids)


def custom_condition(predicate: Callable) -> Condition:
    """用户自定义条件。"""
    return create_condition(predicate)


# ========== 组合器 ==========

def any_of(*conditions: Condition) -> Callable[[Callable], Callable]:
    """或组合：any_of(A, B) → A | B | ..."""

    def decorator(func: Callable) -> Callable:
        final = conditions[0]
        for cond in conditions[1:]:
            final = final | cond
        # 复用 Condition.__call__ 的装饰和注册逻辑
        return final(func)  # type: ignore[return-value]

    return decorator


def all_of(*conditions: Condition) -> Callable[[Callable], Callable]:
    """与组合：all_of(A, B) → A & B & ..."""

    def decorator(func: Callable) -> Callable:
        final = conditions[0]
        for cond in conditions[1:]:
            final = final & cond
        return final(func)  # type: ignore[return-value]

    return decorator


__all__ = [
    "handler",
    "on_group_message",
    "on_private_message",
    "on_at_me",
    "on_keyword",
    "from_user",
    "from_group",
    "custom_condition",
    "any_of",
    "all_of",
]

