from __future__ import annotations

from typing import List, Protocol

from analogai.deepthink.messaging.fact.utils.fact_context import get_current_turn_id
from analogai.deepthink.messaging.fact.services.fact_service import FactServicePort
from analogai.foundation.modules.conditionals.hypothetical_statement import HypotheticalStatement
from analogai.foundation.core.value_objects.cause import Cause
from analogai.foundation.core.value_objects.effect import Effect


class HypotheticalStatementServicePort(Protocol):
    def create(
        self,
        user_id: str,
        agent_id: str,
        causes: List[Cause],
        effect: Effect,
        probability: float = 1.0,
        validity: float = 1.0,
        effect_belief_id: str | None = None,
    ) -> HypotheticalStatement:
        raise NotImplementedError

    def find(self, agent_id: str) -> List[HypotheticalStatement]:
        raise NotImplementedError

    def find_by_agent_id(self, agent_id: str) -> List[HypotheticalStatement]:
        raise NotImplementedError


class HypotheticalStatementLinkingService:
    def __init__(
        self,
        hypothetical_statement_service: HypotheticalStatementServicePort,
        fact_service: FactServicePort,
    ):
        self._hypothetical_statement_service = hypothetical_statement_service
        self._fact_service = fact_service

    def create(
        self,
        user_id: str,
        agent_id: str,
        causes: List[Cause],
        effect: Effect,
        probability: float = 1.0,
        validity: float = 1.0,
        effect_belief_id: str | None = None,
    ) -> HypotheticalStatement:
        statement = self._hypothetical_statement_service.create(
            user_id=user_id,
            agent_id=agent_id,
            causes=causes,
            effect=effect,
            probability=probability,
            validity=validity,
            effect_belief_id=effect_belief_id,
        )
        turn_id = get_current_turn_id()
        statement_id = statement.id
        if turn_id and statement_id:
            self._fact_service.link_hypothetical_statement(str(statement_id), turn_id)
        return statement

    def find(self, agent_id: str) -> List[HypotheticalStatement]:
        return self._hypothetical_statement_service.find(agent_id)

    def find_by_agent_id(self, agent_id: str) -> List[HypotheticalStatement]:
        return self._hypothetical_statement_service.find_by_agent_id(agent_id)
