from __future__ import annotations

from typing import Optional

from analogai.foundation.settings import config as app_config
from analogai.foundation.modules.belief.belief_service import BeliefService
from analogai.foundation.modules.fact.services.fact_service import FactServicePort
from analogai.foundation.modules.fact.factories.fact_factory import FactServiceFactory
from analogai.foundation.modules.fact.repositories.infrastructure.mongo_fact_repository import (
    MongoFactRepository,
)
from analogai.foundation.setup.factories.belief_service_factory import BeliefServiceFactory
from analogai.foundation.modules.fact.source.repositories.fact_source_repository import FactSourceRepository
from analogai.foundation.modules.fact.source.repositories.infrastructure.in_memory_fact_source_repository import (
    InMemoryFactSourceRepository,
)
from analogai.foundation.modules.fact.source.repositories.infrastructure.mongo_fact_source_repository import (
    MongoFactSourceRepository,
)
from analogai.foundation.modules.fact.source.services.fact_source_service import FactSourceService


class FactSourceServiceFactory:
    def __init__(
        self,
        fact_service: Optional[FactServicePort] = None,
        source_repository: Optional[FactSourceRepository] = None,
        belief_service: Optional[BeliefService] = None,
        environment: Optional[str] = None,
    ) -> None:
        self._fact_service = fact_service
        self._source_repository = source_repository
        self._belief_service = belief_service
        self._environment = environment

    def create(self) -> FactSourceService:
        environment = self._environment or app_config.get("ENVIRONMENT", "development")
        if self._belief_service is None:
            self._belief_service = BeliefServiceFactory(environment=environment).get_service()

        statement_service = getattr(self._belief_service, "statement_service", None)
        notion_service = getattr(self._belief_service, "notion_service", None)

        if self._fact_service is None:
            self._fact_service = FactServiceFactory(
                statement_service=statement_service,
                notion_service=notion_service,
            ).create()

        if self._source_repository is None:
            repo = getattr(self._fact_service, "_repository", None)
            if isinstance(repo, MongoFactRepository):
                self._source_repository = MongoFactSourceRepository()
            else:
                self._source_repository = InMemoryFactSourceRepository()

        statement_service = getattr(self._belief_service, "statement_service", None)
        notion_service = getattr(self._belief_service, "notion_service", None)
        if statement_service is not None:
            set_stmt = getattr(self._fact_service, "set_statement_service", None)
            if callable(set_stmt):
                set_stmt(statement_service)
        if notion_service is not None:
            set_notion = getattr(self._fact_service, "set_notion_service", None)
            if callable(set_notion):
                set_notion(notion_service)

        return FactSourceService(
            fact_service=self._fact_service,
            belief_service=self._belief_service,
            source_repository=self._source_repository,
        )
