# app/services/invoice_parser.py
import pytesseract
from pdf2image import convert_from_path
import re
import logging

logger = logging.getLogger(__name__)

class InvoiceParser:
    def __init__(self, tesseract_cmd=None):
        """        Inicializa el parser de facturas.

        Args:
            tesseract_cmd (str, optional): Ruta al ejecutable de Tesseract OCR.
                                         Si es None, se intentará usar la variable de entorno.
        """
        if tesseract_cmd:
            pytesseract.pytesseract.tesseract_cmd = tesseract_cmd
        # En Windows, si Tesseract no está en el PATH, puede que necesites especificar la ruta:
        # self.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
        # pytesseract.pytesseract.tesseract_cmd = self.tesseract_cmd

    def extract_data_from_pdf(self, pdf_path: str) -> dict:
        """
        Extrae datos relevantes de una factura en formato PDF.

        Args:
            pdf_path (str): Ruta al archivo PDF de la factura.

        Returns:
            dict: Un diccionario con los datos extraídos (CUPS, consumos, potencias, coste_actual).
                  Retorna un diccionario vacío o con errores si la extracción falla.
        """
        extracted_data = {
            'cups': None,
            'consumos_energia': {},
            'potencias_contratadas': {},
            'coste_total_factura': None,
            'error': None
        }

        try:
            logger.info(f"Procesando PDF: {pdf_path}")
            images = convert_from_path(pdf_path)
            full_text = ""
            for i, image in enumerate(images):
                logger.debug(f"Extrayendo texto de la página {i+1} del PDF.")
                full_text += pytesseract.image_to_string(image, lang='spa') + "\n"
            
            logger.debug(f"Texto extraído del PDF:\n{full_text[:500]}...") # Loguea una parte del texto

            # --- Lógica de extracción usando expresiones regulares --- 
            # Esta parte es la más compleja y necesitará ajustes basados en formatos de factura reales.

            # Ejemplo para CUPS (ES seguido de 20-22 caracteres alfanuméricos)
            cups_match = re.search(r'(ES\d{4}\w{14,18}|ES\s*\d{4}\s*\w{14,18})', full_text, re.IGNORECASE)
            if cups_match:
                extracted_data['cups'] = cups_match.group(0).replace(" ", "")
                logger.info(f"CUPS encontrado: {extracted_data['cups']}")
            else:
                logger.warning("CUPS no encontrado en el PDF.")

            # Ejemplo para consumo energía P1 (buscando 'consumo.*P1' o 'punta' seguido de kWh)
            # Esto es muy simplificado y necesitará ser mucho más robusto
            # Ejemplo: "Consumo Energía Activa Punta 1.234,56 kWh"
            # Ejemplo: "Energía facturada P1 1.234 kWh"
            consumo_p1_match = re.search(r'(?:consumo energ.a|energ.a facturada|t.rmino de energ.a).*?(P1|Punta).*?(\d[\d.,]*)\s*kWh', full_text, re.IGNORECASE | re.DOTALL)
            if consumo_p1_match:
                try:
                    consumo_str = consumo_p1_match.group(2).replace('.', '').replace(',', '.')
                    extracted_data['consumos_energia']['P1'] = float(consumo_str)
                    logger.info(f"Consumo P1 encontrado: {extracted_data['consumos_energia']['P1']} kWh")
                except ValueError:
                    logger.error(f"Error convirtiendo consumo P1: {consumo_p1_match.group(2)}")
            else:
                logger.warning("Consumo P1 no encontrado.")

            # (Añadir aquí más regex para P2, P3, potencias, coste total, etc.)
            # ...

            # Simulación de extracción de coste total
            coste_total_match = re.search(r'(?:Total Factura|Importe Total|TOTAL A PAGAR).*?(\d[\d.,]*)\s*(?:EUR|€)', full_text, re.IGNORECASE | re.DOTALL)
            if coste_total_match:
                try:
                    coste_str = coste_total_match.group(1).replace('.', '').replace(',', '.')
                    extracted_data['coste_total_factura'] = float(coste_str)
                    logger.info(f"Coste total factura encontrado: {extracted_data['coste_total_factura']} EUR")
                except ValueError:
                    logger.error(f"Error convirtiendo coste total: {coste_total_match.group(1)}")
            else:
                logger.warning("Coste total de la factura no encontrado.")

            if not extracted_data['cups'] and not extracted_data['consumos_energia']:
                extracted_data['error'] = 'No se pudieron extraer datos clave del PDF. Verifique el formato del documento.'
                logger.error(extracted_data['error'])

        except pytesseract.TesseractNotFoundError:
            logger.error("Tesseract no está instalado o no se encuentra en el PATH.")
            extracted_data['error'] = "Error de OCR: Tesseract no encontrado. Por favor, contacte con el administrador."
        except Exception as e:
            logger.error(f"Error procesando PDF con OCR: {e}", exc_info=True)
            extracted_data['error'] = f"Error inesperado al procesar el PDF: {e}"
        
        return extracted_data

# Ejemplo de uso (para pruebas locales):
# if __name__ == '__main__':
#     parser = InvoiceParser(tesseract_cmd=r'C:\Program Files\Tesseract-OCR\tesseract.exe') # Ajusta esta ruta si es necesario
#     # Reemplaza 'ruta/a/tu/factura.pdf' con una factura real para probar
#     data = parser.extract_data_from_pdf('ruta/a/tu/factura.pdf') 
#     print(json.dumps(data, indent=4))
