from typing import Dict, Any, Type
import logging
import importlib

logger = logging.getLogger(__name__)

class ServiceManager:
    _instance = None
    _initialized = False

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super(ServiceManager, cls).__new__(cls)
        return cls._instance

    def __init__(self):
        if not self._initialized:
            self.services: Dict[str, Any] = {}
            self._service_classes = {
                'order_management': 'app.services.external_api.tcgplayer.order_management_service.OrderManagementService',
                'tcgplayer_inventory': 'app.services.external_api.tcgplayer.tcgplayer_inventory_service.TCGPlayerInventoryService',
                'label_printer': 'app.services.label_printer_service.LabelPrinterService',
                'regular_printer': 'app.services.regular_printer_service.RegularPrinterService',
                'address_label': 'app.services.address_label_service.AddressLabelService',
                'pull_sheet': 'app.services.pull_sheet_service.PullSheetService',
                'set_label': 'app.services.set_label_service.SetLabelService',
                'data_initialization': 'app.services.data_initialization.DataInitializationService',
                'scheduler': 'app.services.scheduler.scheduler_service.SchedulerService',
                'file': 'app.services.file_service.FileService',
                'tcgcsv': 'app.services.external_api.tcgcsv.tcgcsv_service.TCGCSVService',
                'mtgjson': 'app.services.external_api.mtgjson.mtgjson_service.MTGJSONService',
                'manabox': 'app.services.manabox_service.ManaboxService',
                'inventory': 'app.services.inventory_service.InventoryService',
                'sealed_box': 'app.services.inventory_service.SealedBoxService',
                'sealed_case': 'app.services.inventory_service.SealedCaseService'

            }
            self._service_configs = {
                'label_printer': {'printer_api_url': "http://192.168.1.110:8000"},
                'regular_printer': {'printer_name': "MFCL2750DW-3"},
                'file': {'base_cache_dir': "app/data/cache"}
            }
            self._initialized = True

    def _import_service(self, module_path: str) -> Type:
        """Dynamically import a service class"""
        module_name, class_name = module_path.rsplit('.', 1)
        module = importlib.import_module(module_name)
        return getattr(module, class_name)

    def register_service(self, service: Any) -> None:
        """Register a service with the service manager"""
        service_name = service.__class__.__name__
        self.services[service_name] = service
        logger.info(f"Service {service_name} registered")

    async def initialize_services(self):
        """Initialize all services"""
        try:
            # Initialize services
            for name, class_path in self._service_classes.items():
                service_class = self._import_service(class_path)
                config = self._service_configs.get(name, {})
                self.services[name] = service_class(**config)
                self.register_service(self.services[name])

            logger.info("All services initialized successfully")
        except Exception as e:
            logger.error(f"Failed to initialize services: {str(e)}")
            raise

    async def cleanup_services(self):
        """Clean up all services"""
        try:
            # Clean up services in reverse order of initialization
            for name, service in reversed(self.services.items()):
                if hasattr(service, 'close'):
                    await service.close()
                elif hasattr(service, 'cleanup'):
                    await service.cleanup()
                logger.info(f"Service {name} cleaned up")

            self.services.clear()
            logger.info("All services cleaned up successfully")
        except Exception as e:
            logger.error(f"Failed to clean up services: {str(e)}")
            raise

    def get_service(self, name: str) -> Any:
        """Get a service by name"""
        if name not in self.services:
            raise ValueError(f"Service {name} not found")
        return self.services[name] 