"""Celery tasks for document extraction pipeline."""

from uuid import UUID

import redis as sync_redis
import structlog

from src.core.config import settings
from src.db.session import get_sync_session
from src.extraction.pipeline import ExtractionPipeline
from src.workers.celery_app import celery_app

logger = structlog.get_logger(__name__)


@celery_app.task(name="extract_document", bind=True, max_retries=3)
def extract_document(self, document_id: str):
    """Extract document using ExtractionPipeline.

    This task processes an uploaded Excel document through the complete
    extraction workflow: table detection, header extraction, merged cell
    resolution, and record building.

    Args:
        document_id: UUID string of the document to process

    Returns:
        Dictionary with extraction summary

    Raises:
        Exception: If extraction fails after retries
    """
    try:
        logger.info(
            "extraction_task_started",
            document_id=document_id,
            task_id=self.request.id,
        )

        # Create Redis client for progress tracking
        redis_client = None
        try:
            redis_client = sync_redis.from_url(
                settings.redis_url, decode_responses=False
            )
        except Exception as e:
            logger.warning(
                "redis_connection_failed",
                error=str(e),
                note="Proceeding without progress tracking",
            )

        # Process document
        with get_sync_session() as session:
            pipeline = ExtractionPipeline(
                db_session=session, redis_client=redis_client
            )
            summary = pipeline.process_document(UUID(document_id))

        logger.info(
            "extraction_task_completed",
            document_id=document_id,
            task_id=self.request.id,
            sheets_processed=summary.sheets_processed,
            records_extracted=summary.records_extracted,
            duration_ms=summary.duration_ms,
        )

        return summary.to_dict()

    except Exception as e:
        logger.error(
            "extraction_task_failed",
            document_id=document_id,
            task_id=self.request.id,
            error=str(e),
            retry_count=self.request.retries,
        )

        # Retry on transient failures
        if self.request.retries < self.max_retries:
            logger.info(
                "extraction_task_retrying",
                document_id=document_id,
                task_id=self.request.id,
                retry_count=self.request.retries + 1,
            )
            raise self.retry(exc=e, countdown=60 * (self.request.retries + 1))

        # Max retries exhausted, re-raise exception
        raise
