"""
Servicio para el cálculo de ahorro energético y la comparación de tarifas.
"""
import os
import logging
from typing import Dict, Any, Optional

# Comprobación de disponibilidad de pandas
PANDAS_AVAILABLE = False
try:
    import pandas as pd
    PANDAS_AVAILABLE = True
except ImportError:
    pass

from .tariff_detector import TariffDetector

# Configuración del logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class TariffComparison:
    """
    Compara los datos de consumo y precios de un cliente con las tarifas de Olé Luz
    para calcular el ahorro potencial.
    """

    def __init__(self):
        """Inicializa el comparador y carga las tarifas de Olé Luz."""
        self._load_oleluz_rates()

    def _load_oleluz_rates(self):
        """
        Carga las tarifas de OLELUZ. En un entorno real, esto vendría de una BD.
        """
        self.oleluz_rates = {
            '2.0TD': {
                'name': 'OLELUZ Fija 2.0TD',
                'energy': {'P1': 0.139, 'P2': 0.095, 'P3': 0.072},
                'power': {'P1': 38.50, 'P2': 10.50}  # Precios en €/kW/año
            },
            '3.0TD': {
                'name': 'Olé Luz 3.0TD',
                'energy': {'P1': 0.144, 'P2': 0.132, 'P3': 0.101, 'P4': 0.092, 'P5': 0.081, 'P6': 0.075},
                'power': {'P1': 37.5, 'P2': 35.2, 'P3': 29.8, 'P4': 27.5, 'P5': 17.2, 'P6': 11.4}
            },
            '6.1TD': {
                'name': 'Olé Luz 6.1TD',
                'energy': {'P1': 0.132, 'P2': 0.121, 'P3': 0.098, 'P4': 0.088, 'P5': 0.079, 'P6': 0.072},
                'power': {'P1': 34.2, 'P2': 32.1, 'P3': 27.9, 'P4': 25.8, 'P5': 16.8, 'P6': 10.9}
            }
        }
        logger.info("Tarifas de Olé Luz cargadas correctamente.")

    def find_matching_rate(self, tariff_type: str) -> Optional[Dict[str, Any]]:
        """Encuentra la tarifa de Olé Luz que corresponde al tipo de peaje del cliente."""
        return self.oleluz_rates.get(tariff_type)

    def _calculate_monthly_cost(self, prices: Dict, client_data: Dict) -> float:
        """Calcula el coste mensual de una factura basado en un conjunto de precios y los datos del cliente."""
        consumption = client_data.get('consumption', {})
        power_contracted = client_data.get('power', {})
        billing_days = client_data.get('billing_period_days', 30)

        energy_prices = prices.get('energy', {})
        power_prices = prices.get('power', {})  # €/kW/año

        energy_cost = sum(consumption.get(p, 0) * energy_prices.get(p, 0) for p in consumption)
        power_cost = sum(power_contracted.get(p, 0) * (power_prices.get(p, 0) / 365 * billing_days) for p in power_contracted)

        subtotal = energy_cost + power_cost
        impuesto_electrico = subtotal * 0.005
        base_imponible_iva = subtotal + impuesto_electrico
        iva = base_imponible_iva * 0.21
        total_cost = base_imponible_iva + iva

        return total_cost

    def calculate_savings(self, client_data: Dict, oleluz_rate: Dict) -> Optional[Dict[str, Any]]:
        """Calcula el ahorro comparando el coste actual del cliente con el que tendría con Olé Luz."""
        current_prices = {
            'energy': client_data.get('current_energy_prices', {}),
            'power': client_data.get('current_power_prices', {})
        }

        if not current_prices['energy'] or not current_prices['power']:
            logger.warning("No se encontraron los precios actuales del cliente. No se puede calcular el ahorro.")
            return None

        current_monthly_cost = self._calculate_monthly_cost(current_prices, client_data)
        oleluz_monthly_cost = self._calculate_monthly_cost(oleluz_rate, client_data)

        monthly_savings = current_monthly_cost - oleluz_monthly_cost
        annual_savings = monthly_savings * 12
        savings_percentage = (monthly_savings / current_monthly_cost) * 100 if current_monthly_cost > 0 else 0

        return {
            'current_total_cost': current_monthly_cost,
            'oleluz_total_cost': oleluz_monthly_cost,
            'monthly_savings': monthly_savings,
            'annual_savings': annual_savings,
            'savings_percentage': savings_percentage,
            'oleluz_rate_used': oleluz_rate
        }

class EnergyCalculator:
    """
    Clase de fachada para interactuar con los datos de una factura energética.
    Utiliza TariffDetector para la extracción de datos.
    """
    def __init__(self):
        """Inicializa el calculador."""
        self.detector = TariffDetector()

    def extract_invoice_data(self, file_path: str) -> Dict[str, Any]:
        """
        Extrae todos los datos relevantes de una factura en PDF.
        """
        try:
            return self.detector.detect_from_pdf(file_path)
        except Exception as e:
            logger.error(f"Error al extraer datos de la factura con TariffDetector: {e}")
            return {}

    def extract_consumption_from_ocr(self, ocr_text: str, tariff_type: str) -> Dict:
        """Extrae los datos de consumo desde el texto OCR."""
        # En una implementación real, esto usaría patrones más complejos
        # Aquí simplificamos con valores predeterminados según el tipo de tarifa
        
        consumption = {'energy_consumption': {}, 'power_contracted': {}}
        
        # Configurar periodos según tipo de tarifa
        periods = TariffDetector.get_tariff_periods(tariff_type)
        
        # Generar datos ficticios para prueba
        # En producción, aquí iría la extracción real de la factura
        if tariff_type == '2.0TD':
            consumption['energy_consumption'] = {
                'P1': 120,  # kWh en periodo punta
                'P2': 180,  # kWh en periodo llano
                'P3': 100   # kWh en periodo valle
            }
            consumption['power_contracted'] = {
                'P1': 4.6,  # kW en periodo punta
                'P2': 4.6   # kW en periodo valle
            }
        else:  # 3.0TD o 6.1TD
            consumption['energy_consumption'] = {
                'P1': 550, 'P2': 650, 'P3': 480,
                'P4': 520, 'P5': 490, 'P6': 700
            }
            consumption['power_contracted'] = {
                'P1': 20, 'P2': 20, 'P3': 20,
                'P4': 20, 'P5': 20, 'P6': 20
            }
        
        consumption['tariff'] = tariff_type
        
        return consumption
    
    @staticmethod
    def get_estimated_current_cost(consumption_data: Dict) -> float:
        """Estima el coste actual basado en los datos de consumo."""
        # En producción, esto vendría del OCR de la factura
        # Aquí simulamos un coste
        
        tariff_type = consumption_data.get('tariff', '2.0TD')
        
        if tariff_type == '2.0TD':
            # Simular precio alto actual
            monthly_cost = 110.0  # Euros/mes con IVA
        elif tariff_type == '3.0TD':
            monthly_cost = 850.0  # Euros/mes con IVA para 3.0TD
        else:  # 6.1TD
            monthly_cost = 3200.0  # Euros/mes con IVA para 6.1TD
            
        return monthly_cost
