"""Daily APScheduler cron for the auto-pin scan.

Single global job at 03:00 UTC. Runs scan_all_users_for_auto_pins so the
system promotes stable note versions before they get aged out of the
rolling cap. Off-hours by design — the scan is cheap but not time-
critical and doesn't need to interrupt regular activity.

Mirrors the BackgroundScheduler + threadsafe-async-call pattern used by
journal_scheduler.py.
"""
from __future__ import annotations

import asyncio
import logging

from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger

from scribe.services.version_pinning import scan_all_users_for_auto_pins

logger = logging.getLogger(__name__)

_scheduler: BackgroundScheduler | None = None
_loop: asyncio.AbstractEventLoop | None = None


def _run_scan_threadsafe() -> None:
    """APScheduler invokes this from a worker thread; bridge into the
    asyncio loop so the scan can await its DB operations."""
    if _loop is None:
        logger.warning("version_pinning scheduler: no loop registered")
        return

    async def _runner():
        try:
            results = await scan_all_users_for_auto_pins()
            total = sum(results.values())
            if total > 0:
                logger.info(
                    "auto-pin scan: pinned %d version(s) across %d user(s)",
                    total, len(results),
                )
            else:
                logger.debug("auto-pin scan: no new pins")
        except Exception:
            logger.exception("auto-pin scan run failed")

    asyncio.run_coroutine_threadsafe(_runner(), _loop)


def start_version_pinning_scheduler(loop: asyncio.AbstractEventLoop) -> None:
    global _scheduler, _loop
    if _scheduler is not None:
        return
    _loop = loop
    _scheduler = BackgroundScheduler()
    _scheduler.add_job(
        _run_scan_threadsafe,
        trigger=CronTrigger(hour=3, minute=0, timezone="UTC"),
        id="version_pinning_auto_scan",
        replace_existing=True,
    )
    _scheduler.start()
    logger.info("Version pinning scheduler started (daily 03:00 UTC)")


def stop_version_pinning_scheduler() -> None:
    global _scheduler
    if _scheduler is not None:
        _scheduler.shutdown(wait=False)
        _scheduler = None
        logger.info("Version pinning scheduler stopped")
