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.agent.settlement.scheduler")

SCHEDULER_TICK_SECONDS = 60
INITIAL_DELAY_SECONDS = 90
BATCH_LIMIT = 200

_scheduler: AsyncIOScheduler | None = None
_last_checked_at: datetime | None = None


async def _job_settle_due_rewards() -> None:
    global _last_checked_at
    log.debug("agent settlement scheduler: tick")
    try:
        async with async_session() as session:
            try:
                settings = await system_setting_service.get_business_settings(session)
                now = datetime.now(timezone.utc)
                interval_seconds = max(60, settings.settlement_check_interval_minutes * 60)
                if _last_checked_at is not None and (now - _last_checked_at).total_seconds() < interval_seconds:
                    return
                _last_checked_at = now
                await session.commit()
            except Exception:
                await session.rollback()
                raise
        result = await task_center_service.run_task("agent_settlement_release", trigger_type="schedule")
        log_task_result(
            log,
            "agent settlement scheduler",
            result,
            activity_keys=("orders", "settlements"),
        )
    except Exception:
        log.exception("agent settlement scheduler failed")


def start_agent_settlement_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_settle_due_rewards,
        IntervalTrigger(seconds=SCHEDULER_TICK_SECONDS, jitter=15, start_date=first_run),
        id="agent_settlement_release",
        next_run_time=first_run,
        max_instances=1,
        coalesce=True,
        misfire_grace_time=300,
    )
    scheduler.start()
    _scheduler = scheduler
    log.debug("agent settlement scheduler started: tick=%ss", SCHEDULER_TICK_SECONDS)


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