"""
Async Engine 独立进程入口
=========================

usage: python -m app.scheduler.main
"""

import asyncio
import logging
import sys

from app.scheduler.engine import AsyncEngine
from app.scheduler.handlers.script_handler import ScriptHandler
from app.scheduler.handlers.subtitle_handler import SubtitleHandler
from app.scheduler.handlers.video_handler import VideoHandler

logger = logging.getLogger("scheduler")


def setup_logging() -> None:
    log_format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    logging.basicConfig(
        level=logging.INFO,
        format=log_format,
        handlers=[logging.StreamHandler(sys.stdout)],
    )


async def _expire_loop(interval_seconds: float = 300.0) -> None:
    """
    定时回收过期积分批次。

    作为独立 task 运行，每 5 分钟执行一次。
    """
    from app.db.session import AsyncSessionLocal
    from app.services import point_service

    while True:
        await asyncio.sleep(interval_seconds)
        try:
            async with AsyncSessionLocal() as db:
                total = await point_service.expire_batches(db)
                await db.commit()
                if total > 0:
                    logger.info(f"[Expire] 回收过期积分 {total} 分")
        except Exception:
            logger.exception("[Expire] 过期积分回收失败")


async def main() -> None:
    setup_logging()

    # 启动过期积分回收定时任务
    asyncio.create_task(_expire_loop(interval_seconds=300.0))
    logger.info("过期积分回收定时任务已启动（间隔 300s）")

    # 初始化共享 HTTP Client
    import httpx

    vidu_client = httpx.AsyncClient(
        timeout=httpx.Timeout(30.0, connect=5.0),
        limits=httpx.Limits(max_connections=20, max_keepalive_connections=20),
    )
    caption_client = httpx.AsyncClient(
        timeout=httpx.Timeout(60.0, connect=5.0),
        limits=httpx.Limits(max_connections=10, max_keepalive_connections=10),
    )

    # 初始化 PlatformGateway（统一调用入口）
    from app.ai.adapters.vidu_adapter import ViduAdapter
    from app.ai.adapters.volcengine_ark_adapter import VolcengineArkAdapter
    from app.ai.adapters.volcengine_caption_adapter import VolcengineCaptionAdapter
    from app.ai.providers.vidu_provider import ViduProvider
    from app.ai.providers.volcengine_caption_provider import VolcengineCaptionProvider
    from app.ai.providers.volcengine_provider import VolcengineProvider
    from app.platform_gateway import PlatformGateway
    from app.services.script_service import get_script_service
    from app.services.vidu_service import ViduService
    from app.services.volcengine_caption_service import VolcengineCaptionService

    platform_gateway = PlatformGateway()

    # Vidu 链路
    vidu_provider = ViduProvider(client=vidu_client)
    vidu_adapter = ViduAdapter(vidu_provider)
    platform_gateway.register("vidu", vidu_adapter)
    vidu_service = ViduService(platform_gateway)
    logger.info("Vidu 链路初始化完成")

    # 火山字幕链路
    caption_service = None
    try:
        caption_provider = VolcengineCaptionProvider(client=caption_client)
        caption_adapter = VolcengineCaptionAdapter(caption_provider)
        platform_gateway.register("volcengine_caption", caption_adapter)
        caption_service = VolcengineCaptionService(platform_gateway)
        logger.info("火山字幕链路初始化完成")
    except Exception as e:
        logger.warning(f"火山字幕链路初始化失败: {e}")

    # 火山方舟链路（脚本生成依赖）
    try:
        volcengine_provider = VolcengineProvider()
        volcengine_ark_adapter = VolcengineArkAdapter(volcengine_provider)
        platform_gateway.register("volcengine_ark", volcengine_ark_adapter)
        logger.info("火山方舟链路初始化完成")
    except Exception as e:
        logger.warning(f"火山方舟链路初始化失败: {e}")

    # 初始化 ModelRouter（传入 Gateway，确保 ScriptHandler 能调用 LLM）
    try:
        from app.ai.model_router import get_model_router

        await get_model_router(gateway=platform_gateway)
        logger.info("ModelRouter 初始化完成")
    except Exception as e:
        logger.warning(f"ModelRouter 初始化失败: {e}")

    engine = AsyncEngine()
    engine.register(SubtitleHandler(service=caption_service))
    engine.register(VideoHandler(service=vidu_service))
    engine.register(ScriptHandler(service=get_script_service()))

    try:
        await engine.run_forever(interval=5.0, min_interval=1.0)
    finally:
        await platform_gateway.close_all()
        await vidu_client.aclose()
        await caption_client.aclose()


if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        logger.info("Scheduler stopped by user")
