"""Celery application factory.

The broker and result backend are both Redis. We deliberately don't use
Postgres as the result backend — Celery's pg result-backend creates noisy
schema artefacts and we already store the structured result on the `jobs`
table.

Tasks register themselves by calling `celery_app.task` in `tasks.py`. Eager
mode (used in tests) is enabled by setting `CELERY_TASK_ALWAYS_EAGER=true`
in the environment.
"""

from __future__ import annotations

import os

from celery import Celery

from ocr_sprint.config import get_settings


def build_celery_app() -> Celery:
    settings = get_settings()
    app = Celery(
        "ocr_sprint",
        broker=settings.redis_url,
        backend=settings.redis_url,
        include=["ocr_sprint.worker.tasks"],
    )
    app.conf.update(
        task_default_queue=settings.celery_task_default_queue,
        task_serializer="json",
        result_serializer="json",
        accept_content=["json"],
        timezone="UTC",
        enable_utc=True,
        task_acks_late=True,
        task_reject_on_worker_lost=True,
        worker_prefetch_multiplier=1,  # OCR is CPU-bound; one task at a time.
        broker_connection_retry_on_startup=True,
        result_expires=24 * 3600,  # results live in DB; redis is just a cache
    )
    if os.getenv("CELERY_TASK_ALWAYS_EAGER", "").lower() in {"1", "true", "yes"}:
        app.conf.task_always_eager = True
        app.conf.task_eager_propagates = True
    return app


celery_app = build_celery_app()
