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.scheduler_log import log_task_result
from app.services import system_setting_service, task_center_service

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

SCHEDULER_TICK_SECONDS = 60
INITIAL_DELAY_SECONDS = 90

_scheduler: AsyncIOScheduler | None = None
_last_sync_at: datetime | None = None


async def _job_sync_zjmf_stock() -> None:
    global _last_sync_at
    try:
        async with async_session() as session:
            settings = await system_setting_service.get_business_settings(session)
            interval_seconds = max(300, int(settings.stock_sync_interval_minutes or 10) * 60)
            now = datetime.now(timezone.utc)
            if _last_sync_at is not None and (now - _last_sync_at).total_seconds() < interval_seconds:
                return
            _last_sync_at = now
            await session.commit()

        result = await task_center_service.run_task("zjmf_stock_sync", trigger_type="schedule")
        log_task_result(
            log,
            "zjmf stock sync scheduler",
            result,
            activity_keys=("updated", "failed", "hidden", "retired"),
        )
    except Exception:
        log.exception("zjmf stock sync scheduler failed")


def start_zjmf_stock_sync_scheduler() -> None:
    global _scheduler
    if _scheduler is not None:
        return
    scheduler = AsyncIOScheduler(timezone="UTC")
    first_run = datetime.now(timezone.utc) + timedelta(seconds=INITIAL_DELAY_SECONDS)
    scheduler.add_job(
        _job_sync_zjmf_stock,
        IntervalTrigger(seconds=SCHEDULER_TICK_SECONDS, jitter=15, start_date=first_run),
        id="zjmf_stock_sync",
        next_run_time=first_run,
        max_instances=1,
        coalesce=True,
        misfire_grace_time=600,
    )
    scheduler.start()
    _scheduler = scheduler
    log.debug("zjmf stock sync scheduler started: tick=%ss", SCHEDULER_TICK_SECONDS)


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