"""Celery configuration for background task processing.

Implements async task queue for:
- Report generation
- Email sending
- Data processing
- Scheduled cleanup tasks
"""

import os
from celery import Celery
from celery.signals import task_prerun, task_postrun, task_failure
from kombu import Queue, Exchange

from src.core.config import settings


# Celery app configuration
celery_app = Celery(
    "mockupaws",
    broker=getattr(settings, "celery_broker_url", "redis://localhost:6379/1"),
    backend=getattr(settings, "celery_result_backend", "redis://localhost:6379/2"),
    include=[
        "src.tasks.reports",
        "src.tasks.emails",
        "src.tasks.cleanup",
        "src.tasks.pricing",
    ],
)

# Celery configuration
celery_app.conf.update(
    # Task settings
    task_serializer="json",
    accept_content=["json"],
    result_serializer="json",
    timezone="UTC",
    enable_utc=True,
    # Task execution
    task_always_eager=False,  # Set to True for testing
    task_store_eager_result=False,
    task_ignore_result=False,
    task_track_started=True,
    # Worker settings
    worker_prefetch_multiplier=4,
    worker_max_tasks_per_child=1000,
    worker_max_memory_per_child=150000,  # 150MB
    # Result backend
    result_expires=3600 * 24,  # 24 hours
    result_extended=True,
    # Task queues
    task_default_queue="default",
    task_queues=(
        Queue("default", Exchange("default"), routing_key="default"),
        Queue("reports", Exchange("reports"), routing_key="reports"),
        Queue("emails", Exchange("emails"), routing_key="emails"),
        Queue("cleanup", Exchange("cleanup"), routing_key="cleanup"),
        Queue("priority", Exchange("priority"), routing_key="priority"),
    ),
    task_routes={
        "src.tasks.reports.*": {"queue": "reports"},
        "src.tasks.emails.*": {"queue": "emails"},
        "src.tasks.cleanup.*": {"queue": "cleanup"},
    },
    # Rate limiting
    task_annotations={
        "src.tasks.reports.generate_pdf_report": {
            "rate_limit": "10/m",
            "time_limit": 300,  # 5 minutes
            "soft_time_limit": 240,  # 4 minutes
        },
        "src.tasks.emails.send_email": {
            "rate_limit": "100/m",
            "time_limit": 60,
        },
    },
    # Task acknowledgments
    task_acks_late=True,
    task_reject_on_worker_lost=True,
    # Retry settings
    task_default_retry_delay=60,  # 1 minute
    task_max_retries=3,
    # Broker settings
    broker_connection_retry=True,
    broker_connection_retry_on_startup=True,
    broker_connection_max_retries=10,
    broker_heartbeat=30,
    # Result backend settings
    result_backend_max_retries=10,
    result_backend_always_retry=True,
)


# Task signals for monitoring
@task_prerun.connect
def task_prerun_handler(task_id, task, args, kwargs, **extras):
    """Handle task pre-run events."""
    from src.core.monitoring import metrics

    metrics.increment_counter("celery_task_started", labels={"task": task.name})


@task_postrun.connect
def task_postrun_handler(task_id, task, args, kwargs, retval, state, **extras):
    """Handle task post-run events."""
    from src.core.monitoring import metrics

    metrics.increment_counter(
        "celery_task_completed",
        labels={"task": task.name, "state": state},
    )


@task_failure.connect
def task_failure_handler(task_id, exception, args, kwargs, traceback, einfo, **extras):
    """Handle task failure events."""
    from src.core.monitoring import metrics
    from src.core.logging_config import get_logger

    logger = get_logger(__name__)
    logger.error(
        "Celery task failed",
        extra={
            "task_id": task_id,
            "exception": str(exception),
            "traceback": traceback,
        },
    )

    task_name = kwargs.get("task", {}).name if "task" in kwargs else "unknown"
    metrics.increment_counter(
        "celery_task_failed",
        labels={"task": task_name, "exception": type(exception).__name__},
    )


# Beat schedule for periodic tasks
celery_app.conf.beat_schedule = {
    "cleanup-old-reports": {
        "task": "src.tasks.cleanup.cleanup_old_reports",
        "schedule": 3600 * 6,  # Every 6 hours
    },
    "cleanup-expired-sessions": {
        "task": "src.tasks.cleanup.cleanup_expired_sessions",
        "schedule": 3600,  # Every hour
    },
    "update-aws-pricing": {
        "task": "src.tasks.pricing.update_aws_pricing",
        "schedule": 3600 * 24,  # Daily
    },
    "health-check": {
        "task": "src.tasks.cleanup.health_check_task",
        "schedule": 60,  # Every minute
    },
}


# Auto-discover tasks
celery_app.autodiscover_tasks()
