# shared/clients/__init__.py
"""
Service Client Factory and Convenient Imports
Provides easy access to all service clients
"""

from .base_service_client import BaseServiceClient, ServiceAuthenticator
from .auth_client import AuthServiceClient
from .training_client import TrainingServiceClient
from .sales_client import SalesServiceClient
from .external_client import ExternalServiceClient
from .forecast_client import ForecastServiceClient
from .inventory_client import InventoryServiceClient
from .orders_client import OrdersServiceClient
from .production_client import ProductionServiceClient
from .recipes_client import RecipesServiceClient
from .suppliers_client import SuppliersServiceClient
from .tenant_client import TenantServiceClient
from .ai_insights_client import AIInsightsClient
from .alerts_client import AlertsServiceClient
from .alert_processor_client import AlertProcessorClient, get_alert_processor_client
from .procurement_client import ProcurementServiceClient
from .distribution_client import DistributionServiceClient

# Import config
from shared.config.base import BaseServiceSettings

# Cache clients to avoid recreating them
_client_cache = {}

def get_training_client(config: BaseServiceSettings = None, service_name: str = "unknown") -> TrainingServiceClient:
    """Get or create a training service client"""
    if config is None:
        from app.core.config import settings as config
    
    cache_key = f"training_{service_name}"
    if cache_key not in _client_cache:
        _client_cache[cache_key] = TrainingServiceClient(config, service_name)
    return _client_cache[cache_key]

def get_sales_client(config: BaseServiceSettings = None, service_name: str = "unknown") -> SalesServiceClient:
    """Get or create a sales service client"""
    if config is None:
        from app.core.config import settings as config
    
    cache_key = f"sales_{service_name}"
    if cache_key not in _client_cache:
        _client_cache[cache_key] = SalesServiceClient(config, service_name)
    return _client_cache[cache_key]

def get_external_client(config: BaseServiceSettings = None, service_name: str = "unknown") -> ExternalServiceClient:
    """Get or create an external service client"""
    if config is None:
        from app.core.config import settings as config
    
    cache_key = f"external_{service_name}"
    if cache_key not in _client_cache:
        _client_cache[cache_key] = ExternalServiceClient(config, service_name)
    return _client_cache[cache_key]

def get_forecast_client(config: BaseServiceSettings = None, service_name: str = "unknown") -> ForecastServiceClient:
    """Get or create a forecast service client"""
    if config is None:
        from app.core.config import settings as config
    
    cache_key = f"forecast_{service_name}"
    if cache_key not in _client_cache:
        _client_cache[cache_key] = ForecastServiceClient(config, service_name)
    return _client_cache[cache_key]

def get_inventory_client(config: BaseServiceSettings = None, service_name: str = "unknown") -> InventoryServiceClient:
    """Get or create an inventory service client"""
    if config is None:
        from app.core.config import settings as config

    cache_key = f"inventory_{service_name}"
    if cache_key not in _client_cache:
        _client_cache[cache_key] = InventoryServiceClient(config, service_name)
    return _client_cache[cache_key]

def get_orders_client(config: BaseServiceSettings = None, service_name: str = "unknown") -> OrdersServiceClient:
    """Get or create an orders service client"""
    if config is None:
        from app.core.config import settings as config
    
    cache_key = f"orders_{service_name}"
    if cache_key not in _client_cache:
        _client_cache[cache_key] = OrdersServiceClient(config)
    return _client_cache[cache_key]

def get_production_client(config: BaseServiceSettings = None, service_name: str = "unknown") -> ProductionServiceClient:
    """Get or create a production service client"""
    if config is None:
        from app.core.config import settings as config

    cache_key = f"production_{service_name}"
    if cache_key not in _client_cache:
        _client_cache[cache_key] = ProductionServiceClient(config, service_name)
    return _client_cache[cache_key]

def get_recipes_client(config: BaseServiceSettings = None, service_name: str = "unknown") -> RecipesServiceClient:
    """Get or create a recipes service client"""
    if config is None:
        from app.core.config import settings as config

    cache_key = f"recipes_{service_name}"
    if cache_key not in _client_cache:
        _client_cache[cache_key] = RecipesServiceClient(config, service_name)
    return _client_cache[cache_key]

def get_suppliers_client(config: BaseServiceSettings = None, service_name: str = "unknown") -> SuppliersServiceClient:
    """Get or create a suppliers service client"""
    if config is None:
        from app.core.config import settings as config

    cache_key = f"suppliers_{service_name}"
    if cache_key not in _client_cache:
        _client_cache[cache_key] = SuppliersServiceClient(config, service_name)
    return _client_cache[cache_key]

def get_alerts_client(config: BaseServiceSettings = None, service_name: str = "unknown") -> AlertsServiceClient:
    """Get or create an alerts service client"""
    if config is None:
        from app.core.config import settings as config

    cache_key = f"alerts_{service_name}"
    if cache_key not in _client_cache:
        _client_cache[cache_key] = AlertsServiceClient(config, service_name)
    return _client_cache[cache_key]

def get_tenant_client(config: BaseServiceSettings = None, service_name: str = "unknown") -> TenantServiceClient:
    """Get or create a tenant service client"""
    if config is None:
        from app.core.config import settings as config

    cache_key = f"tenant_{service_name}"
    if cache_key not in _client_cache:
        _client_cache[cache_key] = TenantServiceClient(config)
    return _client_cache[cache_key]

def get_procurement_client(config: BaseServiceSettings = None, service_name: str = "unknown") -> ProcurementServiceClient:
    """Get or create a procurement service client"""
    if config is None:
        from app.core.config import settings as config

    cache_key = f"procurement_{service_name}"
    if cache_key not in _client_cache:
        _client_cache[cache_key] = ProcurementServiceClient(config, service_name)
    return _client_cache[cache_key]

def get_distribution_client(config: BaseServiceSettings = None, service_name: str = "unknown") -> DistributionServiceClient:
    """Get or create a distribution service client"""
    if config is None:
        from app.core.config import settings as config

    cache_key = f"distribution_{service_name}"
    if cache_key not in _client_cache:
        _client_cache[cache_key] = DistributionServiceClient(config, service_name)
    return _client_cache[cache_key]


# Note: get_alert_processor_client is already defined in alert_processor_client.py
# and imported above, so we don't need to redefine it here


class ServiceClients:
    """Convenient wrapper for all service clients"""
    
    def __init__(self, config: BaseServiceSettings = None, service_name: str = "unknown"):
        self.service_name = service_name
        self.config = config or self._get_default_config()
        
        # Initialize clients lazily
        self._training_client = None
        self._sales_client = None
        self._external_client = None
        self._forecast_client = None
        self._inventory_client = None
        self._orders_client = None
        self._production_client = None
        self._recipes_client = None
        self._suppliers_client = None
    
    def _get_default_config(self):
        """Get default config from app settings"""
        try:
            from app.core.config import settings
            return settings
        except ImportError:
            raise ImportError("Could not import app config. Please provide config explicitly.")
    
    @property
    def training(self) -> TrainingServiceClient:
        """Get training service client"""
        if self._training_client is None:
            self._training_client = get_training_client(self.config, self.service_name)
        return self._training_client
    
    @property
    def sales(self) -> SalesServiceClient:
        """Get sales service client"""
        if self._sales_client is None:
            self._sales_client = get_sales_client(self.config, self.service_name)
        return self._sales_client
    
    @property
    def external(self) -> ExternalServiceClient:
        """Get external service client"""
        if self._external_client is None:
            self._external_client = get_external_client(self.config, self.service_name)
        return self._external_client
    
    @property
    def forecast(self) -> ForecastServiceClient:
        """Get forecast service client"""
        if self._forecast_client is None:
            self._forecast_client = get_forecast_client(self.config, self.service_name)
        return self._forecast_client
    
    @property
    def inventory(self) -> InventoryServiceClient:
        """Get inventory service client"""
        if self._inventory_client is None:
            self._inventory_client = get_inventory_client(self.config, self.service_name)
        return self._inventory_client
    
    @property
    def orders(self) -> OrdersServiceClient:
        """Get orders service client"""
        if self._orders_client is None:
            self._orders_client = get_orders_client(self.config, self.service_name)
        return self._orders_client
    
    @property
    def production(self) -> ProductionServiceClient:
        """Get production service client"""
        if self._production_client is None:
            self._production_client = get_production_client(self.config, self.service_name)
        return self._production_client
    
    @property
    def recipes(self) -> RecipesServiceClient:
        """Get recipes service client"""
        if self._recipes_client is None:
            self._recipes_client = get_recipes_client(self.config, self.service_name)
        return self._recipes_client
    
    @property
    def suppliers(self) -> SuppliersServiceClient:
        """Get suppliers service client"""
        if self._suppliers_client is None:
            self._suppliers_client = get_suppliers_client(self.config, self.service_name)
        return self._suppliers_client

# Convenience function to get all clients
def get_service_clients(config: BaseServiceSettings = None, service_name: str = "unknown") -> ServiceClients:
    """Get a wrapper with all service clients"""
    return ServiceClients(config, service_name)

# Export all classes for direct import
__all__ = [
    'BaseServiceClient',
    'ServiceAuthenticator',
    'AuthServiceClient',
    'TrainingServiceClient',
    'SalesServiceClient',
    'ExternalServiceClient',
    'ForecastServiceClient',
    'InventoryServiceClient',
    'OrdersServiceClient',
    'ProductionServiceClient',
    'RecipesServiceClient',
    'SuppliersServiceClient',
    'AlertsServiceClient',
    'AlertProcessorClient',
    'TenantServiceClient',
    'DistributionServiceClient',
    'ServiceClients',
    'get_training_client',
    'get_sales_client',
    'get_external_client',
    'get_forecast_client',
    'get_inventory_client',
    'get_orders_client',
    'get_production_client',
    'get_recipes_client',
    'get_suppliers_client',
    'get_alerts_client',
    'get_alert_processor_client',
    'get_tenant_client',
    'get_procurement_client',
    'get_distribution_client',
    'get_service_clients',
    'create_forecast_client'
]
# Backward compatibility aliases
create_forecast_client = get_forecast_client
