from __future__ import annotations

import logging
from datetime import datetime, timedelta, timezone

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

from src.database import connect
from src.services.system_service import auto_backup

logger = logging.getLogger(__name__)
scheduler = BackgroundScheduler(timezone="Asia/Jakarta")
_bot = None


def _delete(chat_id: int, message_id: int, job_id: int | None = None) -> None:
    try:
        if _bot:
            _bot.delete_message(chat_id, message_id)
    except Exception:
        logger.debug("Pesan sudah terhapus/tidak dapat dihapus", exc_info=True)
    finally:
        if job_id:
            with connect() as connection:
                connection.execute("DELETE FROM delete_jobs WHERE id=?", (job_id,))


def _run_auto_backup() -> None:
    try:
        auto_backup()
    except Exception:
        logger.exception("Backup otomatis gagal")


def schedule_delete(bot, chat_id: int, message_id: int, seconds: int) -> None:
    global _bot
    _bot = bot
    run_at = datetime.now(timezone.utc) + timedelta(seconds=max(1, seconds))
    with connect() as connection:
        connection.execute(
            "DELETE FROM delete_jobs WHERE chat_id=? AND message_id=?",
            (chat_id, message_id),
        )
        job_id = connection.execute(
            "INSERT INTO delete_jobs(chat_id,message_id,run_at) VALUES(?,?,?)",
            (chat_id, message_id, run_at.isoformat()),
        ).lastrowid
    scheduler.add_job(
        _delete,
        "date",
        run_date=run_at,
        args=[chat_id, message_id, job_id],
        id=f"del-{chat_id}-{message_id}",
        replace_existing=True,
        misfire_grace_time=3600,
    )


def start(bot) -> None:
    global _bot
    _bot = bot
    if not scheduler.running:
        scheduler.start()

    scheduler.add_job(
        _run_auto_backup,
        CronTrigger(hour=3, minute=0, timezone="Asia/Jakarta"),
        id="daily-database-backup",
        replace_existing=True,
        coalesce=True,
        misfire_grace_time=6 * 3600,
    )

    now = datetime.now(timezone.utc)
    with connect() as connection:
        jobs = connection.execute("SELECT * FROM delete_jobs").fetchall()
    for job in jobs:
        try:
            run_at = datetime.fromisoformat(job["run_at"])
            if run_at.tzinfo is None:
                run_at = run_at.replace(tzinfo=timezone.utc)
        except Exception:
            run_at = now
        if run_at <= now:
            _delete(job["chat_id"], job["message_id"], job["id"])
        else:
            scheduler.add_job(
                _delete,
                "date",
                run_date=run_at,
                args=[job["chat_id"], job["message_id"], job["id"]],
                id=f"del-{job['chat_id']}-{job['message_id']}",
                replace_existing=True,
                misfire_grace_time=3600,
            )
