"""
Celery Application Configuration
Background task processing with Redis as broker
"""
from celery import Celery
from celery.schedules import crontab
from kombu import Queue, Exchange

from app.config import settings


def make_celery() -> Celery:
    """Create and configure Celery application"""

    celery_app = Celery(
        "ai_chatbot_workers",
        broker=settings.REDIS_URL,
        backend=settings.REDIS_URL,
        include=[
            "app.workers.tasks.invoice_tasks",
            "app.workers.tasks.usage_tasks",
            "app.workers.tasks.email_tasks",
            "app.workers.tasks.training_tasks",
            "app.workers.tasks.cleanup_tasks",
            "app.workers.tasks.webhook_tasks",
            "app.workers.tasks.payment_tasks",
        ]
    )

    # Celery Configuration
    celery_app.conf.update(
        # Task settings
        task_serializer="json",
        accept_content=["json"],
        result_serializer="json",
        timezone="Asia/Kolkata",
        enable_utc=True,

        # Task execution settings
        task_acks_late=True,
        task_reject_on_worker_lost=True,
        task_time_limit=3600,  # 1 hour hard limit
        task_soft_time_limit=3300,  # 55 min soft limit

        # Worker settings
        worker_prefetch_multiplier=1,
        worker_concurrency=4,
        worker_max_tasks_per_child=1000,

        # Result settings
        result_expires=86400,  # 24 hours
        result_extended=True,

        # Error handling
        task_track_started=True,
        task_default_retry_delay=60,  # 1 minute
        task_max_retries=3,

        # Queue settings
        task_default_queue="default",
        task_queues=(
            Queue("default", Exchange("default"), routing_key="default"),
            Queue("high_priority", Exchange("high_priority"), routing_key="high_priority"),
            Queue("low_priority", Exchange("low_priority"), routing_key="low_priority"),
            Queue("emails", Exchange("emails"), routing_key="emails"),
            Queue("invoices", Exchange("invoices"), routing_key="invoices"),
            Queue("analytics", Exchange("analytics"), routing_key="analytics"),
        ),

        # Task routing
        task_routes={
            "app.workers.tasks.email_tasks.*": {"queue": "emails"},
            "app.workers.tasks.invoice_tasks.*": {"queue": "invoices"},
            "app.workers.tasks.usage_tasks.*": {"queue": "analytics"},
            "app.workers.tasks.training_tasks.*": {"queue": "low_priority"},
            "app.workers.tasks.cleanup_tasks.*": {"queue": "low_priority"},
        },

        # Beat schedule (cron jobs)
        beat_schedule={
            # Invoice generation - 1st of every month at 1:00 AM
            "generate-monthly-invoices": {
                "task": "app.workers.tasks.invoice_tasks.generate_all_invoices",
                "schedule": crontab(hour=1, minute=0, day_of_month=1),
                "options": {"queue": "invoices"},
            },

            # Send invoice reminders - daily at 9:00 AM
            "send-invoice-reminders": {
                "task": "app.workers.tasks.invoice_tasks.send_invoice_reminders",
                "schedule": crontab(hour=9, minute=0),
                "options": {"queue": "invoices"},
            },

            # Mark overdue invoices - daily at 2:00 AM
            "mark-overdue-invoices": {
                "task": "app.workers.tasks.invoice_tasks.mark_overdue_invoices",
                "schedule": crontab(hour=2, minute=0),
                "options": {"queue": "invoices"},
            },

            # Process failed payments - every 6 hours
            "process-failed-payments": {
                "task": "app.workers.tasks.payment_tasks.process_failed_payments",
                "schedule": crontab(hour="*/6", minute=30),
                "options": {"queue": "invoices"},
            },

            # Aggregate daily usage - every night at midnight
            "aggregate-daily-usage": {
                "task": "app.workers.tasks.usage_tasks.aggregate_daily_usage",
                "schedule": crontab(hour=0, minute=0),
                "options": {"queue": "analytics"},
            },

            # Aggregate monthly usage - 1st of every month at 00:30 AM
            "aggregate-monthly-usage": {
                "task": "app.workers.tasks.usage_tasks.aggregate_monthly_usage",
                "schedule": crontab(hour=0, minute=30, day_of_month=1),
                "options": {"queue": "analytics"},
            },

            # Check usage limits - every hour
            "check-usage-limits": {
                "task": "app.workers.tasks.usage_tasks.check_usage_limits",
                "schedule": crontab(minute=0),
                "options": {"queue": "analytics"},
            },

            # Cleanup old sessions - daily at 3:00 AM
            "cleanup-expired-sessions": {
                "task": "app.workers.tasks.cleanup_tasks.cleanup_expired_sessions",
                "schedule": crontab(hour=3, minute=0),
                "options": {"queue": "low_priority"},
            },

            # Cleanup old logs - weekly on Sunday at 4:00 AM
            "cleanup-old-logs": {
                "task": "app.workers.tasks.cleanup_tasks.cleanup_old_logs",
                "schedule": crontab(hour=4, minute=0, day_of_week=0),
                "options": {"queue": "low_priority"},
            },

            # Process pending webhooks - every 5 minutes
            "process-pending-webhooks": {
                "task": "app.workers.tasks.webhook_tasks.process_pending_webhooks",
                "schedule": crontab(minute="*/5"),
                "options": {"queue": "default"},
            },

            # Generate analytics reports - daily at 6:00 AM
            "generate-daily-reports": {
                "task": "app.workers.tasks.usage_tasks.generate_daily_reports",
                "schedule": crontab(hour=6, minute=0),
                "options": {"queue": "analytics"},
            },

            # Health check - every 15 minutes
            "worker-health-check": {
                "task": "app.workers.tasks.cleanup_tasks.health_check",
                "schedule": crontab(minute="*/15"),
                "options": {"queue": "default"},
            },
        },

        # Beat settings
        beat_schedule_filename="celerybeat-schedule",
    )

    return celery_app


# Create Celery app instance
celery = make_celery()


# Task decorators for common patterns
def high_priority_task(*args, **kwargs):
    """Decorator for high priority tasks"""
    kwargs.setdefault("queue", "high_priority")
    return celery.task(*args, **kwargs)


def low_priority_task(*args, **kwargs):
    """Decorator for low priority tasks"""
    kwargs.setdefault("queue", "low_priority")
    return celery.task(*args, **kwargs)
