import shutil
from datetime import datetime
from pathlib import Path
from zoneinfo import ZoneInfo

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

from app.settings import settings
from app.utils.logger import get_logger

logger = get_logger("scheduler")

HANDWRITING_CLEANUP_SUBFOLDERS = [
    "success",
    "failed",
]


def get_retention_days(subfolder: str) -> int:
    if subfolder == "success":
        return settings.HANDWRITING_RETENTION_DAYS_SUCCESS
    if subfolder == "failed":
        return settings.HANDWRITING_RETENTION_DAYS_FAILED
    return settings.HANDWRITING_RETENTION_DAYS_SUCCESS


def delete_old_directories(folder_path: Path, retention_days: int):
    today = datetime.now(ZoneInfo(settings.APP_TIMEZONE)).date()
    deleted_count = 0
    kept_count = 0
    invalid_count = 0

    for entry in folder_path.iterdir():
        if not entry.is_dir():
            continue

        try:
            folder_date = datetime.strptime(entry.name, "%Y-%m-%d").date()
        except ValueError:
            invalid_count += 1
            continue

        age_days = (today - folder_date).days

        if age_days > retention_days:
            shutil.rmtree(entry, ignore_errors=True)
            deleted_count += 1
        else:
            kept_count += 1

    total_count = deleted_count + kept_count
    logger.info(
        (
            "Cleanup summary | folder=%s retention_days=%s total=%s "
            "deleted=%s kept=%s invalid=%s"
        ),
        folder_path,
        retention_days,
        total_count,
        deleted_count,
        kept_count,
        invalid_count,
    )


def cleanup_handwriting_directories():
    """
    Main scheduled cleanup job.
    """
    if not settings.HANDWRITING_PRESERVE_DIR:
        logger.warning("HANDWRITING_PRESERVE_DIR not configured. Skipping cleanup.")
        return

    base_path = Path(settings.HANDWRITING_PRESERVE_DIR)

    if not base_path.exists():
        logger.warning(f"Preserve directory not found: {base_path}")
        return

    logger.info(
        "Cleanup started | Retention days success=%s failed=%s",
        get_retention_days("success"),
        get_retention_days("failed"),
    )

    for subfolder in HANDWRITING_CLEANUP_SUBFOLDERS:
        folder_path = base_path / subfolder

        if not folder_path.exists():
            logger.warning(f"Subfolder missing: {folder_path}")
            continue

        delete_old_directories(folder_path, get_retention_days(subfolder))

    logger.info("Cleanup finished successfully.")


# ------------------------------------------------------------------
# SCHEDULER SETUP
# ------------------------------------------------------------------
scheduler = BackgroundScheduler(timezone=settings.APP_TIMEZONE)


def start_scheduler():
    """
    Register and start scheduled jobs only if RUN_CRON is enabled.
    """

    if not settings.RUN_CRON:
        logger.info("RUN_CRON is disabled. Scheduler will not start.")
        return

    if scheduler.running:
        logger.info("Scheduler already running. Skipping start.")
        return

    scheduler.add_job(
        cleanup_handwriting_directories,
        CronTrigger(hour=2, minute=0, timezone=settings.APP_TIMEZONE),
        id="handwriting_cleanup_job",
        replace_existing=True,
        max_instances=1,
        coalesce=True,
        misfire_grace_time=3600,
    )

    scheduler.start()
    logger.info(f"APScheduler started.")


def shutdown_scheduler():
    if scheduler.running:
        scheduler.shutdown(wait=False)
        logger.info("APScheduler stopped immediately.")
