"""
任务管理器 - 统一管理所有定时任务
"""
import logging
from typing import Dict, Any, List, Type
from apscheduler.schedulers.background import BackgroundScheduler
from .base import BaseTask

logger = logging.getLogger(__name__)


class TaskManager:
    """任务管理器 - 单例模式"""

    _instance = None

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self):
        if not hasattr(self, 'initialized'):
            self.scheduler = BackgroundScheduler()
            self.tasks: Dict[str, BaseTask] = {}
            self.initialized = True

    def register(self, task_class: Type[BaseTask]) -> Type[BaseTask]:
        """
        注册任务（装饰器模式）

        使用方式:
            @task_manager.register
            class MyTask(IntervalTask):
                SCHEDULE_INTERVAL = 5
                ...
        """
        if not issubclass(task_class, BaseTask):
            raise TypeError(f"{task_class} 必须继承自 BaseTask")

        # 创建任务实例
        task = task_class()
        self.tasks[task.name] = task

        # 自动调度
        if task_class.should_schedule():
            trigger = task_class.get_trigger()
            self.scheduler.add_job(
                func=task,
                trigger=trigger,
                id=task.job_id,
                name=task.name,
                replace_existing=True
            )
            logger.info(f"✓ 已注册并调度任务: {task.name} | 触发器: {trigger}")
        else:
            logger.info(f"✓ 已注册任务: {task.name} (未调度)")

        return task_class

    def register_many(self, task_classes: List[Type[BaseTask]]):
        """批量注册任务"""
        for task_class in task_classes:
            self.register(task_class)

    def start(self):
        """启动调度器"""
        if not self.scheduler.running:
            self.scheduler.start()
            logger.info("任务调度器已启动")

    def shutdown(self):
        """关闭调度器"""
        if self.scheduler.running:
            self.scheduler.shutdown()
            logger.info("任务调度器已关闭")

    def trigger(self, task_name: str) -> Any:
        """手动触发任务"""
        if task_name not in self.tasks:
            raise ValueError(f"任务不存在: {task_name}")

        logger.info(f"手动触发任务: {task_name}")
        return self.tasks[task_name]()

    def get_task(self, task_name: str) -> BaseTask:
        """获取任务实例"""
        return self.tasks.get(task_name)

    def list_tasks(self) -> List[Dict[str, Any]]:
        """列出所有任务"""
        return [
            {
                "name": task.name,
                "description": task.description.strip(),
                "scheduled": task.__class__.should_schedule(),
                "trigger": str(task.__class__.get_trigger()) if task.__class__.should_schedule() else None,
                "job_id": task.job_id
            }
            for task in self.tasks.values()
        ]

    def list_jobs(self) -> List[Dict[str, Any]]:
        """列出所有调度任务"""
        jobs = self.scheduler.get_jobs()
        return [
            {
                "id": job.id,
                "name": job.name,
                "trigger": str(job.trigger),
                "next_run": job.next_run_time.isoformat() if job.next_run_time else None
            }
            for job in jobs
        ]


# 全局单例
task_manager = TaskManager()