# !/usr/bin/env python
# -*-coding:utf-8 -*-

"""
定时任务管理器

负责:
- 管理调度器生命周期
- 自动加载任务模块
- 提供健康检查接口
- 集成到 FastAPI 生命周期
"""

from typing import Optional, Dict, Any
from pathlib import Path

from fastapi import FastAPI
from loguru import logger

from infoman.config import settings


class SchedulerManager:
    """定时任务管理器"""

    def __init__(self, timezone: str = 'Asia/Shanghai'):
        """
        初始化管理器

        Args:
            timezone: 时区，默认 Asia/Shanghai
        """
        self.timezone = timezone
        self.scheduler = None
        self.initialized = False

    @property
    def is_available(self) -> bool:
        """调度器是否可用"""
        return self.scheduler is not None and self.scheduler.is_running

    async def startup(self, app: Optional[FastAPI] = None) -> bool:
        if self.initialized:
            logger.warning("⚠️ SchedulerManager 已初始化，跳过重复初始化")
            return True

        # 检查是否启用调度器
        scheduler_enabled = getattr(settings, 'SCHEDULER_ENABLED', True)
        if not scheduler_enabled:
            logger.info("⏭️ 调度器已禁用，跳过初始化")
            return False

        # 延迟导入调度器
        try:
            from infoman.service.infrastructure.scheduler.scheduler import get_scheduler
        except ImportError as e:
            logger.error(f"❌ APScheduler 依赖未安装: {e}")
            logger.error("请运行: pip install infomankit[scheduler]")
            return False

        logger.info("🚀 初始化定时任务调度器...")

        try:
            # 获取调度器实例
            self.scheduler = get_scheduler()

            # 自动加载任务模块
            await self._load_scheduled_tasks()

            # 启动调度器
            self.scheduler.start()

            # 挂载到 app.state（如果提供了 app）
            if app:
                app.state.scheduler = self.scheduler
                logger.debug("✅ 调度器已挂载到 app.state")

            self.initialized = True
            return True

        except Exception as e:
            logger.error(f"❌ 调度器启动失败: {e}")
            return False

    async def shutdown(self):
        """关闭调度器"""
        if not self.initialized:
            return

        logger.info("⏹️ 关闭定时任务调度器...")

        try:
            if self.scheduler:
                self.scheduler.shutdown(wait=False)
                logger.success("✅ 调度器已关闭")

        except Exception as e:
            logger.error(f"❌ 调度器关闭失败: {e}")

        finally:
            self.initialized = False

    async def _load_scheduled_tasks(self):
        try:
            from infoman.service.utils.module_loader import register_event_handlers
        except ImportError as e:
            logger.warning(f"⚠️ 无法导入模块加载器: {e}")
            return

        # 尝试常见的任务目录
        possible_paths = [
            ("app.schedulers", "./app/schedulers"),
            (settings.SCHEDULER_PACKAGE, settings.SCHEDULER_PATH),
        ]

        # 支持从配置读取自定义路径
        if hasattr(settings, 'SCHEDULER_PACKAGE') and hasattr(settings, 'SCHEDULER_PATH'):
            possible_paths.insert(0, (settings.SCHEDULER_PACKAGE, settings.SCHEDULER_PATH))

        loaded_any = False
        for package, folder in possible_paths:
            project_root = Path.cwd()
            loaded_modules = register_event_handlers(
                package=package,
                folder=folder,
                base_path=project_root
            )

            if loaded_modules:
                loaded_any = True
                logger.info(f"📦 从 {folder} 加载了 {len(loaded_modules)} 个任务模块")
                break

        if not loaded_any:
            logger.info(
                "ℹ️ 未找到定时任务目录，跳过自动加载。"
                "如需使用定时任务，请创建 app/schedulers 目录"
            )

    async def health_check(self) -> Dict[str, Any]:
        scheduler_enabled = getattr(settings, 'SCHEDULER_ENABLED', True)
        if not scheduler_enabled:
            return {
                "status": "not_configured",
                "name": "scheduler",
                "details": {"enabled": False}
            }

        if not self.initialized or not self.scheduler:
            return {
                "status": "unhealthy",
                "name": "scheduler",
                "details": {"error": "未初始化"}
            }

        try:
            # 检查调度器状态
            if self.scheduler.is_running:
                jobs = self.scheduler.get_jobs()
                return {
                    "status": "healthy",
                    "name": "scheduler",
                    "details": {
                        "running": True,
                        "timezone": self.timezone,
                        "job_count": len(jobs),
                    }
                }
            else:
                return {
                    "status": "unhealthy",
                    "name": "scheduler",
                    "details": {
                        "running": False,
                        "error": "调度器未运行"
                    }
                }

        except Exception as e:
            return {
                "status": "unhealthy",
                "name": "scheduler",
                "details": {"error": str(e)}
            }

    async def get_stats(self) -> Dict[str, Any]:
        if not self.is_available:
            return {}

        jobs = self.scheduler.get_jobs()
        return {
            "running": self.scheduler.is_running,
            "timezone": self.timezone,
            "job_count": len(jobs),
            "jobs": [
                {
                    "id": job.id,
                    "name": job.name,
                    "next_run_time": job.next_run_time.isoformat() if job.next_run_time else None,
                }
                for job in jobs
            ]
        }
