"""
factory.py
----------
Factory for creating storage backends.
"""

from typing import Optional, Dict, Any
from hieromem_api.settings import get_settings
from hieromem_core.backends.interface import VectorBackend, GraphBackend


def get_vector_backend(config: Optional[Dict[str, Any]] = None) -> VectorBackend:
    """
    Get configured vector backend.

    Configuration can come from arguments or global settings.
    """
    settings = get_settings()
    backend_type = (config and config.get("type")) or settings.memory_backend or "faiss"

    if backend_type == "pgvector":
        from hieromem_core.backends.vector.pgvector import PGVectorBackend

        dsn = (config and config.get("dsn")) or settings.pgvector_dsn
        return PGVectorBackend(dsn=dsn)

    elif backend_type == "pinecone":
        from hieromem_core.backends.vector.pinecone import PineconeBackend

        api_key = config and config.get("api_key")
        env = config and config.get("environment")
        index_name = config and config.get("index_name")
        return PineconeBackend(api_key=api_key, environment=env, index_name=index_name)

    elif backend_type == "weaviate":
        from hieromem_core.backends.vector.weaviate import WeaviateBackend

        url = config and config.get("url")
        return WeaviateBackend(url=url)

    elif backend_type == "faiss":
        from hieromem_core.backends.vector.faiss import FaissBackend

        return FaissBackend()

    else:
        raise ValueError(f"Unknown vector backend type: {backend_type}")


def get_graph_backend(config: Optional[Dict[str, Any]] = None) -> GraphBackend:
    """Get configured graph backend."""
    settings = get_settings()
    backend_type = (config and config.get("type")) or "in_memory"

    if backend_type == "neo4j":
        from hieromem_core.backends.graph.neo4j import Neo4jBackend

        uri = (config and config.get("uri")) or settings.neo4j_uri
        user = (config and config.get("user")) or settings.neo4j_user
        password = (config and config.get("password")) or settings.neo4j_password
        return Neo4jBackend(uri=uri, user=user, password=password)

    elif backend_type == "neptune":
        from hieromem_core.backends.graph.neptune import NeptuneBackend

        endpoint = config and config.get("endpoint")
        return NeptuneBackend(endpoint=endpoint)

    elif backend_type == "in_memory":
        from hieromem_core.backends.graph.in_memory import InMemoryGraphBackend

        return InMemoryGraphBackend()

    else:
        raise ValueError(f"Unknown graph backend type: {backend_type}")
