"""Subscription Celery tasks.

Periodic tasks for subscription lifecycle management:

``check_expiring_trials``
    Runs every 6 hours.  Emits ``subscription.trial_expiring_soon`` for
    tenants whose trial ends within the next 3 days (and haven't been notified
    yet today).

``expire_subscriptions``
    Runs every hour.  Marks subscriptions whose ``current_period_end`` is in
    the past as ``expired`` (if currently ``active`` or ``trial``).

``expire_addon_features``
    Runs every hour.  Hard-deletes (or deactivates) add-on features whose
    ``expires_at`` has passed.
"""

from __future__ import annotations

import datetime
import logging

from celery import shared_task
from django.utils import timezone

logger = logging.getLogger(__name__)


@shared_task(name="subscription.check_expiring_trials")
def check_expiring_trials() -> dict:
    """Emit ``subscription.trial_expiring_soon`` for trials ending in ≤3 days."""
    from simorgh.apps.events.bus import dispatch
    from simorgh.apps.subscription.models import SubscriptionStatus, TenantSubscription

    now = timezone.now()
    warning_threshold = now + datetime.timedelta(days=3)

    qs = TenantSubscription.objects.filter(
        status=SubscriptionStatus.TRIAL,
        trial_ends_at__lte=warning_threshold,
        trial_ends_at__gt=now,
    ).select_related("plan")

    count = 0
    for sub in qs:
        dispatch(
            "subscription.trial_expiring_soon",
            payload={
                "tenant_id": sub.tenant_id,
                "trial_ends_at": sub.trial_ends_at.isoformat(),
            },
        )
        count += 1

    logger.info("subscription.check_expiring_trials: notified %d trials", count)
    return {"notified": count}


@shared_task(name="subscription.expire_subscriptions")
def expire_subscriptions() -> dict:
    """Mark subscriptions past their ``current_period_end`` as expired."""
    from simorgh.apps.subscription.models import SubscriptionStatus, TenantSubscription

    now = timezone.now()
    updated = TenantSubscription.objects.filter(
        status__in=[SubscriptionStatus.ACTIVE, SubscriptionStatus.TRIAL],
        current_period_end__lt=now,
    ).update(status=SubscriptionStatus.EXPIRED)

    logger.info("subscription.expire_subscriptions: expired %d subscriptions", updated)
    return {"expired": updated}


@shared_task(name="subscription.expire_addon_features")
def expire_addon_features() -> dict:
    """Emit ``subscription.addon_expired`` and delete expired add-on features."""
    from simorgh.apps.events.bus import dispatch
    from simorgh.apps.subscription.models import TenantAddonFeature

    now = timezone.now()
    expired_qs = TenantAddonFeature.objects.filter(
        expires_at__lt=now,
    ).select_related()

    count = 0
    for addon in expired_qs:
        dispatch(
            "subscription.addon_expired",
            payload={
                "tenant_id": addon.tenant_id,
                "feature_key": addon.feature_key,
            },
        )
        count += 1

    expired_qs.delete()

    logger.info("subscription.expire_addon_features: removed %d expired addons", count)
    return {"removed": count}
