"""
Celery tasks for quota management and grace period enforcement.

These tasks run periodically to:
1. Check for new quota overages across all tenants
2. Send reminder emails (7 days, 1 day before grace period ends)
3. Auto-archive resources when grace period expires
"""

from celery import shared_task
from django.utils import timezone
import logging

logger = logging.getLogger(__name__)


@shared_task
def check_all_tenant_quotas():
    """
    Check all tenants for quota overages and create QuotaOverage records.

    This task should run daily (or after plan changes) to detect new overages.

    Returns:
        dict: Summary of overages found and notifications sent
    """
    from smoothschedule.tenants.models import Tenant
    from .quota_service import check_tenant_quotas

    results = {
        'tenants_checked': 0,
        'new_overages': 0,
        'notifications_sent': 0,
        'errors': [],
    }

    # Get all active tenants
    tenants = Tenant.objects.filter(is_active=True)

    for tenant in tenants:
        try:
            results['tenants_checked'] += 1
            overages = check_tenant_quotas(tenant)

            for overage in overages:
                results['new_overages'] += 1
                if overage.initial_email_sent_at:
                    results['notifications_sent'] += 1

        except Exception as e:
            error_msg = f"Error checking tenant {tenant.id}: {str(e)}"
            logger.error(error_msg, exc_info=True)
            results['errors'].append(error_msg)

    logger.info(
        f"Quota check complete: {results['tenants_checked']} tenants checked, "
        f"{results['new_overages']} new overages, "
        f"{results['notifications_sent']} notifications sent"
    )

    return results


@shared_task
def send_quota_reminder_emails():
    """
    Send reminder emails for active quota overages approaching deadline.

    Sends:
    - 7-day reminder (if not already sent)
    - 1-day reminder (if not already sent)

    This task should run daily.

    Returns:
        dict: Summary of reminders sent
    """
    from .quota_service import send_grace_period_reminders

    results = {
        'week_reminders_sent': 0,
        'day_reminders_sent': 0,
        'errors': [],
    }

    try:
        reminder_results = send_grace_period_reminders()
        results['week_reminders_sent'] = reminder_results.get('week_reminders_sent', 0)
        results['day_reminders_sent'] = reminder_results.get('day_reminders_sent', 0)

    except Exception as e:
        error_msg = f"Error sending reminder emails: {str(e)}"
        logger.error(error_msg, exc_info=True)
        results['errors'].append(error_msg)

    logger.info(
        f"Quota reminders sent: {results['week_reminders_sent']} week reminders, "
        f"{results['day_reminders_sent']} day reminders"
    )

    return results


@shared_task
def process_expired_quotas():
    """
    Process quota overages where grace period has expired.

    Auto-archives oldest resources for each expired overage.

    This task should run daily, preferably early morning.

    Returns:
        dict: Summary of auto-archiving actions taken
    """
    from .quota_service import process_expired_grace_periods

    results = {
        'overages_processed': 0,
        'resources_archived': 0,
        'errors': [],
    }

    try:
        archive_results = process_expired_grace_periods()
        results['overages_processed'] = archive_results.get('overages_processed', 0)
        results['resources_archived'] = archive_results.get('total_archived', 0)

    except Exception as e:
        error_msg = f"Error processing expired quotas: {str(e)}"
        logger.error(error_msg, exc_info=True)
        results['errors'].append(error_msg)

    logger.info(
        f"Expired quotas processed: {results['overages_processed']} overages, "
        f"{results['resources_archived']} resources archived"
    )

    return results


@shared_task
def check_single_tenant_quotas(tenant_id: int):
    """
    Check quotas for a single tenant.

    Use this when a tenant changes plans (upgrade/downgrade).

    Args:
        tenant_id: ID of the tenant to check

    Returns:
        dict: Overages found for this tenant
    """
    from smoothschedule.tenants.models import Tenant
    from .quota_service import check_tenant_quotas

    try:
        tenant = Tenant.objects.get(id=tenant_id)
        overages = check_tenant_quotas(tenant)

        return {
            'tenant_id': tenant_id,
            'tenant_name': tenant.name,
            'overages_found': len(overages),
            'overages': [
                {
                    'quota_type': o.quota_type,
                    'current_usage': o.current_usage,
                    'allowed_limit': o.allowed_limit,
                    'overage_amount': o.overage_amount,
                    'grace_period_ends_at': o.grace_period_ends_at.isoformat(),
                }
                for o in overages
            ]
        }

    except Tenant.DoesNotExist:
        logger.error(f"Tenant {tenant_id} not found")
        return {'error': f'Tenant {tenant_id} not found'}

    except Exception as e:
        logger.error(f"Error checking tenant {tenant_id}: {str(e)}", exc_info=True)
        return {'error': str(e)}


@shared_task
def resolve_tenant_overage(overage_id: int):
    """
    Check if a specific quota overage has been resolved.

    Call this after a tenant archives resources or upgrades plan.

    Args:
        overage_id: ID of the QuotaOverage to check

    Returns:
        dict: Resolution status
    """
    from .models import QuotaOverage
    from .quota_service import QuotaService

    try:
        overage = QuotaOverage.objects.select_related('tenant').get(id=overage_id)

        if overage.status != 'ACTIVE':
            return {
                'overage_id': overage_id,
                'already_resolved': True,
                'status': overage.status,
            }

        # Get current usage
        service = QuotaService(overage.tenant)
        current_usage = service.get_current_usage(overage.quota_type)
        allowed_limit = service.get_limit(overage.quota_type)

        if current_usage <= allowed_limit:
            # Overage resolved!
            overage.resolve()
            return {
                'overage_id': overage_id,
                'resolved': True,
                'current_usage': current_usage,
                'allowed_limit': allowed_limit,
            }
        else:
            # Still over limit
            overage.current_usage = current_usage
            overage.overage_amount = current_usage - allowed_limit
            overage.save()

            return {
                'overage_id': overage_id,
                'resolved': False,
                'current_usage': current_usage,
                'allowed_limit': allowed_limit,
                'still_over_by': current_usage - allowed_limit,
            }

    except QuotaOverage.DoesNotExist:
        logger.error(f"QuotaOverage {overage_id} not found")
        return {'error': f'QuotaOverage {overage_id} not found'}

    except Exception as e:
        logger.error(f"Error resolving overage {overage_id}: {str(e)}", exc_info=True)
        return {'error': str(e)}


@shared_task
def cleanup_old_resolved_overages(days_to_keep: int = 90):
    """
    Clean up old resolved/archived quota overage records.

    Args:
        days_to_keep: Keep records from the last N days (default: 90)

    Returns:
        int: Number of records deleted
    """
    from .models import QuotaOverage
    from datetime import timedelta

    cutoff_date = timezone.now() - timedelta(days=days_to_keep)

    # Only delete resolved or archived overages
    deleted_count, _ = QuotaOverage.objects.filter(
        status__in=['RESOLVED', 'ARCHIVED', 'CANCELLED'],
        updated_at__lt=cutoff_date
    ).delete()

    logger.info(f"Deleted {deleted_count} old quota overage records")
    return deleted_count
