"""
Dramatiq Worker Starter Actor Base
==================================

Actor 基类，提供便捷的 Actor 定义方式
"""

import logging

import dramatiq

logger = logging.getLogger(__name__)


class ActorBase:
    """
    Actor 基类。

    提供便捷的 Actor 定义方式，支持装饰器语法。
    """

    @classmethod
    def actor(
        cls,
        queue_name: str = "default",
        max_retries: int = 0,
        min_backoff: int = 1000,
        max_backoff: int = 900000,
        **kwargs,
    ):
        """
        Actor 装饰器

        :param queue_name: 队列名称
        :type queue_name: str
        :param max_retries: 最大重试次数
        :type max_retries: int
        :param min_backoff: 最小退避时间（毫秒）
        :type min_backoff: int
        :param max_backoff: 最大退避时间（毫秒）
        :type max_backoff: int
        :param **kwargs: 其他 dramatiq.actor 参数
        :return: 装饰器函数

        Example::

            @ActorBase.actor(queue_name="custom")
            def my_task(data: str) -> str:
                return data.upper()
        """

        def decorator(func):
            # 创建 Actor
            actor = dramatiq.actor(
                queue_name=queue_name,
                max_retries=max_retries,
                min_backoff=min_backoff,
                max_backoff=max_backoff,
                **kwargs,
            )(func)

            logger.info(f"Registered actor: {actor.actor_name} on queue: {queue_name}")
            return actor

        return decorator

    @classmethod
    def send(
        cls,
        actor_name: str,
        *args,
        **kwargs,
    ):
        """
        发送任务消息

        :param actor_name: Actor 名称
        :type actor_name: str
        :param *args: 位置参数
        :param **kwargs: 关键字参数
        :return: dramatiq.Message 实例
        :rtype: dramatiq.Message

        Example::

            ActorBase.send("my_task", "hello")
        """
        broker = dramatiq.get_broker()
        actor = broker.get_actor(actor_name)
        return actor.send(*args, **kwargs)

    @classmethod
    def send_with_options(
        cls,
        actor_name: str,
        *args,
        delay: int | None = None,
        **kwargs,
    ):
        """
        发送任务消息（带选项）

        :param actor_name: Actor 名称
        :type actor_name: str
        :param *args: 位置参数
        :param delay: 延迟执行时间（毫秒）
        :type delay: int | None
        :param **kwargs: 关键字参数
        :return: dramatiq.Message 实例
        :rtype: dramatiq.Message

        Example::

            ActorBase.send_with_options("my_task", "hello", delay=5000)
        """
        broker = dramatiq.get_broker()
        actor = broker.get_actor(actor_name)
        if delay is not None:
            return actor.send_with_options(args=args, kwargs=kwargs, delay=delay)
        return actor.send(*args, **kwargs)
