"""魔方云接口的连通性巡检调度。

- 间隔：23 小时（与 token TTL 21600s/6h 解耦，避免和业务调用并发抢同一把 token）。
- 启动时延迟 30s 跑一次首检（让 FastAPI 应用先就绪），之后每 23h 一次。
- 每次跑完，结果会写回 cloud_servers.status + Redis `qycw:dcim_cloud:status:{id}`。
"""
from __future__ import annotations

import logging
from datetime import datetime, timedelta, timezone

from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.triggers.interval import IntervalTrigger

from app.database import async_session
from app.services.cloud_server_service import refresh_all_servers

log = logging.getLogger("qycw.cloud_server.scheduler")

CHECK_INTERVAL_HOURS = 23
INITIAL_DELAY_SECONDS = 30

_scheduler: AsyncIOScheduler | None = None


async def _job_refresh_all() -> None:
    log.debug("cloud_server refresh: tick")
    try:
        async with async_session() as session:
            summary = await refresh_all_servers(session)
        ok_n = sum(1 for _, ok, _ in summary if ok)
        if ok_n == len(summary):
            log.debug("cloud_server refresh: done, %d/%d online", ok_n, len(summary))
        else:
            log.warning("cloud_server refresh: done, %d/%d online", ok_n, len(summary))
    except Exception:
        log.exception("cloud_server refresh: failed")


def start_scheduler() -> None:
    global _scheduler
    if _scheduler is not None:
        return
    sched = AsyncIOScheduler(timezone="UTC")
    first_run = datetime.now(timezone.utc) + timedelta(seconds=INITIAL_DELAY_SECONDS)
    sched.add_job(
        _job_refresh_all,
        IntervalTrigger(hours=CHECK_INTERVAL_HOURS, jitter=60, start_date=first_run),
        id="cloud_server_refresh",
        next_run_time=first_run,
        max_instances=1,
        coalesce=True,
        misfire_grace_time=600,
    )
    sched.start()
    _scheduler = sched
    log.debug("cloud_server scheduler started: interval=%dh", CHECK_INTERVAL_HOURS)


def shutdown_scheduler() -> None:
    global _scheduler
    if _scheduler is None:
        return
    _scheduler.shutdown(wait=False)
    _scheduler = None
