from fastapi import HTTPException
import base64
import logging
from core.celery_app import celery_app
from celery import current_task, states
from core.database import CoreSessionLocal 

from .mex.service import ConsolidadoImportacionMexService

logger = logging.getLogger(__name__)

@celery_app.task(name="generar_pdf_consolidado_async", bind=True)
def generar_pdf_consolidado_async(self, invoice_id: int, company_id: int):
   
    # 1. Abrimos conexión a la DB
    db = CoreSessionLocal()
    try:
        logger.info(f"Worker procesando consolidado {invoice_id}...")
        
        # 2. Instanciamos el servicio de reportes
        service = ConsolidadoImportacionMexService()

        # Update state to PROCESSING
        self.update_state(state='PROCESSING', meta={'current': 5, 'total': 100, 'status': 'Iniciando generación...'})
        
        def progress_callback(progress: int, status: str):
            self.update_state(state='PROCESSING', meta={'current': progress, 'total': 100, 'status': status})

        # 3. Generamos los bytes del PDF
        pdf_bytes, nombre, media_type = service.generar_factura_completa(
            db=db, 
            invoice_id=invoice_id, 
            company_id=company_id,
            progress_callback=progress_callback
        )
        
        # 4. Codificamos a base64 para que viaje seguro por Valkey
        pdf_base64 = base64.b64encode(pdf_bytes).decode('utf-8')
        
        return {
            "status": "success",
            "file_name": nombre,
            "content": pdf_base64,
            "media_type": media_type
        }

    except HTTPException as e:
        logger.error(f"HTTP Error en Celery Worker: {str(e.detail)}")
        return {"status": "error", "message": str(e.detail)}
    except Exception as e:
        logger.error(f"Error en Celery Worker: {str(e)}")
        return {"status": "error", "message": f"Error interno en el servidor de reportes: {str(e)}"}
    finally:
        # 5. MUY IMPORTANTE: Cerramos la conexión para no saturar Postgres
        db.close()
