from __future__ import annotations

from datetime import datetime, timedelta

from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.interval import IntervalTrigger
from loguru import logger

from backend.app.core.config import load_config
from backend.app.scraper.runner import scrape_all

scheduler = BackgroundScheduler(timezone=load_config().scrape.timezone)
"""Scheduler interne APScheduler, prêt à déclencher scrape_all selon la config."""


def start_scheduler() -> None:
    if scheduler.running:
        return

    config = load_config()
    interval = config.scrape.interval_minutes
    # Premier run après l'intervalle défini (pas immédiatement au démarrage)
    first_run = datetime.now() + timedelta(minutes=interval)
    scheduler.add_job(
        scrape_all,
        trigger=IntervalTrigger(minutes=interval),
        id="scheduled-scrape-all",
        replace_existing=True,
        next_run_time=first_run,
    )
    scheduler.start()
    logger.info("Scheduler démarré avec un intervalle de {} minutes (prochain run: {})", interval, first_run.strftime("%H:%M:%S"))


def get_scheduler_status() -> dict:
    """Retourne l'état actuel du scheduler."""
    job = scheduler.get_job("scheduled-scrape-all")
    config = load_config()

    status = {
        "running": scheduler.running,
        "interval_minutes": config.scrape.interval_minutes,
        "job_exists": job is not None,
        "next_run_time": None,
        "next_run_in_minutes": None,
    }

    if job and job.next_run_time:
        status["next_run_time"] = job.next_run_time.isoformat()
        # Calculer le temps restant
        now = datetime.now(job.next_run_time.tzinfo)
        delta = job.next_run_time - now
        status["next_run_in_minutes"] = round(delta.total_seconds() / 60, 1)

    return status


def trigger_next_run() -> dict:
    """Force le prochain scrape à s'exécuter maintenant."""
    job = scheduler.get_job("scheduled-scrape-all")
    if not job:
        return {"success": False, "error": "Job non trouvé"}

    # Modifier le job pour s'exécuter maintenant
    scheduler.modify_job("scheduled-scrape-all", next_run_time=datetime.now())
    logger.info("Prochain scrape programmé pour maintenant")
    return {"success": True, "message": "Scrape programmé pour exécution immédiate"}
