from __future__ import annotations

from abc import ABC, abstractmethod
from typing import List, Optional

from analogai.deepthink.messaging.fact.fact import Fact


class FactRepositoryPort(ABC):
    @abstractmethod
    def register_turn(self, user_id: str, agent_id: str, turn_id: str) -> None:
        raise NotImplementedError

    @abstractmethod
    def save_fact(self, fact: Fact) -> None:
        raise NotImplementedError

    @abstractmethod
    def get_fact(self, id: str) -> Optional[Fact]:
        raise NotImplementedError

    @abstractmethod
    def update_facts_statement_id(self, turn_id: str, statement_id: str) -> None:
        raise NotImplementedError

    @abstractmethod
    def update_facts_notion_id(self, turn_id: str, notion_id: str) -> None:
        raise NotImplementedError

    @abstractmethod
    def update_facts_hypothetical_statement_id(self, turn_id: str, statement_id: str) -> None:
        raise NotImplementedError

    @abstractmethod
    def get_facts_for_turn(self, turn_id: str) -> List[Fact]:
        raise NotImplementedError

    @abstractmethod
    def get_turn_ids(self, user_id: str, agent_id: str) -> List[str]:
        raise NotImplementedError

    @abstractmethod
    def link_statement(self, statement_id: str, turn_id: str) -> None:
        raise NotImplementedError

    @abstractmethod
    def link_belief(self, belief_id: str, turn_id: str) -> None:
        raise NotImplementedError

    @abstractmethod
    def link_notion(self, notion_id: str, turn_id: str) -> None:
        raise NotImplementedError

    @abstractmethod
    def link_hypothetical_statement(self, statement_id: str, turn_id: str) -> None:
        raise NotImplementedError

    @abstractmethod
    def get_turn_id_for_statement(self, statement_id: str) -> Optional[str]:
        raise NotImplementedError

    @abstractmethod
    def get_turn_id_for_belief(self, belief_id: str) -> Optional[str]:
        raise NotImplementedError

    @abstractmethod
    def get_turn_id_for_notion(self, notion_id: str) -> Optional[str]:
        raise NotImplementedError

    @abstractmethod
    def get_turn_id_for_hypothetical_statement(self, statement_id: str) -> Optional[str]:
        raise NotImplementedError

    @abstractmethod
    def search_text(self, user_id: str, agent_id: str, query: str, top_k: int) -> List[Fact]:
        raise NotImplementedError

    @abstractmethod
    def search_similar(
        self,
        user_id: str,
        agent_id: str,
        embedding: List[float],
        top_k: int,
        similarity_cutoff: Optional[float] = None,
    ) -> List[Fact]:
        raise NotImplementedError
