from __future__ import annotations

from analogai.foundation.modules.fact.services.fact_service import FactServicePort
from analogai.foundation.modules.fact.subscribers.fact_observer_registry import (
    FactObserverRegistry,
)
from analogai.foundation.modules.fact.subscribers.statement_fact_subscriber import (
    StatementFactSubscriber,
)
from analogai.foundation.modules.fact.subscribers.notion_fact_subscriber import (
    NotionFactSubscriber,
)
from analogai.foundation.modules.fact.subscribers.hypothetical_statement_fact_subscriber import (
    HypotheticalStatementFactSubscriber,
)


class FactObserverBuilder:
    def __init__(
        self,
        fact_service: FactServicePort,
        registry: FactObserverRegistry,
    ) -> None:
        self._fact_service = fact_service
        self._registry = registry

    def observe_statement_service(self, statement_service: object) -> "FactObserverBuilder":
        if statement_service is None:
            return self
        self._ensure_observer(
            statement_service,
            StatementFactSubscriber,
            StatementFactSubscriber(self._fact_service, self._registry),
        )
        return self

    def observe_notion_service(self, notion_service: object) -> "FactObserverBuilder":
        if notion_service is None:
            return self
        self._ensure_observer(
            notion_service,
            NotionFactSubscriber,
            NotionFactSubscriber(self._fact_service, self._registry),
        )
        return self

    def observe_hypothetical_statement_service(
        self,
        hypothetical_statement_service: object,
    ) -> "FactObserverBuilder":
        if hypothetical_statement_service is None:
            return self
        self._ensure_observer(
            hypothetical_statement_service,
            HypotheticalStatementFactSubscriber,
            HypotheticalStatementFactSubscriber(self._fact_service, self._registry),
        )
        return self

    @staticmethod
    def _ensure_observer(service: object, observer_type: type, observer: object) -> None:
        existing = getattr(service, "_observers", None)
        if isinstance(existing, list):
            for item in existing:
                if isinstance(item, observer_type):
                    return
        add_observer = getattr(service, "add_observer", None)
        if callable(add_observer):
            add_observer(observer)


__all__ = ["FactObserverBuilder"]
