# Copyright (c) 2025 Patrick Motsch
# All rights reserved.
"""Plugin-discovery registry for accounting connectors (analogous to aicoreModelRegistry)."""

import glob
import importlib
import inspect
import logging
import os
from typing import Dict, List, Optional

from .accountingConnectorBase import BaseAccountingConnector

logger = logging.getLogger(__name__)


class AccountingRegistry:
    """Discovers and manages accounting connector plugins."""

    _connectors: Dict[str, BaseAccountingConnector] = {}
    _discovered: bool = False

    def discoverConnectors(self) -> int:
        """Scan connectors/ for accountingConnector*.py files and register them."""
        if self._discovered:
            return len(self._connectors)

        connectorsDir = os.path.join(os.path.dirname(__file__), "connectors")
        pattern = os.path.join(connectorsDir, "accountingConnector*.py")

        for filePath in glob.glob(pattern):
            moduleName = os.path.splitext(os.path.basename(filePath))[0]
            fullModuleName = f"modules.features.trustee.accounting.connectors.{moduleName}"
            try:
                module = importlib.import_module(fullModuleName)
                for _name, obj in inspect.getmembers(module, inspect.isclass):
                    if issubclass(obj, BaseAccountingConnector) and obj is not BaseAccountingConnector:
                        instance = obj()
                        connectorType = instance.getConnectorType()
                        self._connectors[connectorType] = instance
                        logger.info(f"Registered accounting connector: {connectorType}")
            except Exception as e:
                logger.error(f"Failed to load accounting connector from {moduleName}: {e}")

        self._discovered = True
        logger.info(f"Discovered {len(self._connectors)} accounting connector(s)")
        return len(self._connectors)

    def getConnector(self, connectorType: str) -> Optional[BaseAccountingConnector]:
        """Return the connector instance for the given type."""
        if not self._discovered:
            self.discoverConnectors()
        return self._connectors.get(connectorType)

    def getAvailableConnectors(self) -> List[Dict]:
        """Return metadata for all available connectors (for frontend dropdown)."""
        if not self._discovered:
            self.discoverConnectors()
        result = []
        for connectorType, connector in self._connectors.items():
            fields = []
            for f in connector.getRequiredConfigFields():
                fd = f.model_dump()
                fd["label"] = f.label
                fields.append(fd)
            result.append({
                "connectorType": connectorType,
                "label": connector.getConnectorLabel(),
                "configFields": fields,
            })
        return result


_registryInstance: Optional[AccountingRegistry] = None


def _getAccountingRegistry() -> AccountingRegistry:
    """Singleton access to the accounting registry."""
    global _registryInstance
    if _registryInstance is None:
        _registryInstance = AccountingRegistry()
        _registryInstance.discoverConnectors()
    return _registryInstance
