"""Daily APScheduler cron that purges expired trash.

Mirrors version_pinning_scheduler.py: a single global BackgroundScheduler job
at 03:30 UTC bridges into the asyncio loop to run the async purge. Iterates
every user and applies that user's own `trash_retention_days` setting; 0
disables auto-purge for that user.
"""
from __future__ import annotations

import asyncio
import logging

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

from scribe.services import trash as trash_svc
from scribe.services.settings import get_setting

logger = logging.getLogger(__name__)

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


def _run_purge_threadsafe() -> None:
    """APScheduler invokes this from a worker thread; bridge into the loop."""
    if _loop is None:
        logger.warning("trash scheduler: no loop registered")
        return

    async def _runner():
        try:
            from sqlalchemy import select

            from scribe.models import async_session
            from scribe.models.user import User

            async with async_session() as session:
                user_ids = (await session.execute(select(User.id))).scalars().all()

            purged = 0
            for uid in user_ids:
                raw = await get_setting(uid, "trash_retention_days", "90")
                try:
                    days = int(raw)
                except (TypeError, ValueError):
                    days = 90
                purged += await trash_svc.purge_expired(uid, days)
            if purged:
                logger.info("trash purge: removed %d expired row(s)", purged)
            else:
                logger.debug("trash purge: nothing expired")
        except Exception:
            logger.exception("trash purge run failed")

    asyncio.run_coroutine_threadsafe(_runner(), _loop)


def start_trash_scheduler(loop: asyncio.AbstractEventLoop) -> None:
    global _scheduler, _loop
    if _scheduler is not None:
        return
    _loop = loop
    _scheduler = BackgroundScheduler()
    _scheduler.add_job(
        _run_purge_threadsafe,
        trigger=CronTrigger(hour=3, minute=30, timezone="UTC"),
        id="trash_retention_purge",
        replace_existing=True,
    )
    _scheduler.start()
    logger.info("Trash retention scheduler started (daily 03:30 UTC)")


def stop_trash_scheduler() -> None:
    global _scheduler
    if _scheduler is not None:
        _scheduler.shutdown(wait=False)
        _scheduler = None
        logger.info("Trash retention scheduler stopped")
