"""
Cron jobs for enrichment rollover system.

Usage:
    python -m src.fmatch.saas.cron.enrichment_rollover_jobs monthly-cap
    python -m src.fmatch.saas.cron.enrichment_rollover_jobs daily-expiry
"""

import asyncio
import logging
import sys
from datetime import datetime

from ..db import AsyncSessionLocal
from ..config.enrichment import ENRICHMENT_ENABLED
from ..services.enrichment_bucket_manager import apply_rollover_cap, expire_old_buckets
from ..models import UsageQuotaModel
from sqlalchemy import select

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


async def monthly_rollover_cap_job():
    """
    Apply rollover cap to all accounts (1× monthly allowance).

    Run on 1st of month at 00:05 UTC.
    """
    if not ENRICHMENT_ENABLED:
        logger.info("[CRON] Skipping monthly rollover cap job - enrichment disabled")
        return

    logger.info("[CRON] Starting monthly rollover cap job")
    start_time = datetime.utcnow()

    async with AsyncSessionLocal() as db:
        # Get all accounts with active quotas
        result = await db.execute(
            select(UsageQuotaModel).where(UsageQuotaModel.tier.in_(["pro", "scale"]))
        )
        quotas = result.scalars().all()

        total_accounts = len(quotas)
        processed = 0
        clipped_total = 0

        for quota in quotas:
            try:
                clipped = await apply_rollover_cap(
                    account_id=quota.account_id, tier=quota.tier, db=db
                )

                if clipped:
                    logger.info(
                        f"[CRON] Clipped {clipped} credits for {quota.account_id} ({quota.tier})"
                    )
                    clipped_total += clipped

                processed += 1

            except Exception as e:
                logger.error(
                    f"[CRON] Failed to cap rollover for {quota.account_id}: {e}"
                )

        duration = (datetime.utcnow() - start_time).total_seconds()
        logger.info(
            f"[CRON] Monthly rollover cap job complete: "
            f"{processed}/{total_accounts} accounts processed, "
            f"{clipped_total} total credits clipped, "
            f"duration={duration:.2f}s"
        )


async def daily_expiry_job():
    """
    Expire old buckets past their expiration date.

    Run daily at 00:10 UTC.
    """
    if not ENRICHMENT_ENABLED:
        logger.info("[CRON] Skipping daily expiry job - enrichment disabled")
        return

    logger.info("[CRON] Starting daily expiry job")
    start_time = datetime.utcnow()

    async with AsyncSessionLocal() as db:
        try:
            expired_count = await expire_old_buckets(db=db)

            duration = (datetime.utcnow() - start_time).total_seconds()
            logger.info(
                f"[CRON] Daily expiry job complete: "
                f"{expired_count} buckets expired, "
                f"duration={duration:.2f}s"
            )

        except Exception as e:
            logger.error(f"[CRON] Daily expiry job failed: {e}", exc_info=True)
            raise


def main():
    """Command-line entry point."""
    if len(sys.argv) < 2:
        print(
            "Usage: python -m src.fmatch.saas.cron.enrichment_rollover_jobs <job-name>"
        )
        print("Jobs: monthly-cap, daily-expiry")
        sys.exit(1)

    job_name = sys.argv[1]

    if job_name == "monthly-cap":
        asyncio.run(monthly_rollover_cap_job())
    elif job_name == "daily-expiry":
        asyncio.run(daily_expiry_job())
    else:
        print(f"Unknown job: {job_name}")
        print("Available jobs: monthly-cap, daily-expiry")
        sys.exit(1)


if __name__ == "__main__":
    main()
