"""
任务基类 - 简化版调度系统
"""
import logging
from abc import ABC, abstractmethod
from datetime import datetime
from typing import Optional, Any

from apscheduler.triggers.base import BaseTrigger
from apscheduler.triggers.cron import CronTrigger
from apscheduler.triggers.interval import IntervalTrigger
from sqlalchemy.orm import Session

logger = logging.getLogger(__name__)


class BaseTask(ABC):
    """
    任务基类 - 所有任务的父类
    """

    # 调度配置
    SCHEDULE_ENABLED: bool = True
    SCHEDULE_JOB_ID: Optional[str] = None

    def __init__(self):
        self.name = self.__class__.__name__
        self.description = self.__doc__ or ""
        self.logger = logging.getLogger(f"task.{self.name}")
        self.job_id = self.SCHEDULE_JOB_ID or f"job_{self.name}"

    @abstractmethod
    def execute(self) -> Any:
        """执行任务逻辑（子类必须实现）"""
        pass

    def __call__(self) -> Any:
        """使任务可调用"""
        self.logger.info(f"开始执行任务: {self.name}")
        start_time = datetime.now()

        try:
            result = self.execute()
            duration = (datetime.now() - start_time).total_seconds()
            self.logger.info(f"任务完成: {self.name}, 耗时: {duration:.2f}秒")
            return result

        except Exception as e:
            self.logger.error(f"任务执行失败: {self.name}, 错误: {str(e)}", exc_info=True)
            raise

    @classmethod
    def get_trigger(cls) -> Optional[BaseTrigger]:
        """获取触发器（子类重写）"""
        return None

    @classmethod
    def should_schedule(cls) -> bool:
        """是否应该调度"""
        return cls.SCHEDULE_ENABLED and cls.get_trigger() is not None


class DatabaseTask(BaseTask):
    """
    数据库任务基类 - 自动管理数据库会话
    """

    def __init__(self):
        super().__init__()
        # 延迟导入避免循环依赖
        from ..database.session_manager import get_session_manager
        self.session_manager = get_session_manager()

    @abstractmethod
    def execute_with_db(self, db: Session) -> Any:
        """执行任务（子类必须实现）"""
        pass

    def execute(self) -> Any:
        """自动处理数据库会话"""
        with self.session_manager.session_scope() as db:
            return self.execute_with_db(db)


class IntervalTask(DatabaseTask):
    """
    间隔任务基类

    示例:
        class MyTask(IntervalTask):
            SCHEDULE_INTERVAL = 5  # 每5分钟执行一次

            def execute_with_db(self, db):
                # 任务逻辑
                pass
    """
    SCHEDULE_INTERVAL: Optional[int] = None  # 间隔分钟数

    @classmethod
    def get_trigger(cls) -> Optional[BaseTrigger]:
        if cls.SCHEDULE_INTERVAL:
            return IntervalTrigger(minutes=cls.SCHEDULE_INTERVAL)
        return None


class CronTask(DatabaseTask):
    """
    Cron任务基类

    示例:
        class MyTask(CronTask):
            SCHEDULE_CRON = "0 0 * * *"  # 每天0点执行

            def execute_with_db(self, db):
                # 任务逻辑
                pass
    """
    SCHEDULE_CRON: Optional[str] = None  # Cron表达式

    @classmethod
    def get_trigger(cls) -> Optional[BaseTrigger]:
        if cls.SCHEDULE_CRON:
            return CronTrigger.from_crontab(cls.SCHEDULE_CRON)
        return None


class SimpleTask(BaseTask):
    """
    简单任务基类 - 不需要数据库连接

    示例:
        class MyTask(SimpleTask):
            SCHEDULE_INTERVAL = 10

            def execute(self):
                # 任务逻辑
                pass
    """
    SCHEDULE_INTERVAL: Optional[int] = None
    SCHEDULE_CRON: Optional[str] = None

    @classmethod
    def get_trigger(cls) -> Optional[BaseTrigger]:
        if cls.SCHEDULE_CRON:
            return CronTrigger.from_crontab(cls.SCHEDULE_CRON)
        elif cls.SCHEDULE_INTERVAL:
            return IntervalTrigger(minutes=cls.SCHEDULE_INTERVAL)
        return None
