from typing import Optional, Callable

from analogai.deepthink.application.value_objects.user_agent import UserAgent
from analogai.deepthink.presentation.preprocessing.previous_messages_stack import PreviousMessagesStack
from analogai.deepthink.internal.processors.deepthinker_processor import DeepthinkPipelineProcessor
from analogai.deepthink.messaging.question_answering.enums.synthesized_text_type import (
    SynthesizedTextType,
)


class DeepthinkEngine:
    def __init__(
        self,
        processor: DeepthinkPipelineProcessor,
        on_close: Optional[Callable[[], None]] = None,
    ):
        self._processor = processor
        self._on_close = on_close

    def close(self) -> None:
        if self._on_close is not None:
            self._on_close()

    def deepthink(
        self,
        input_text: str,
        user_agent: Optional[UserAgent] = None,
        previous_messages_stack: Optional[PreviousMessagesStack] = None,
    ) -> Optional[str]:
        return self._processor.deepthink(
            input_text=input_text,
            user_agent=user_agent,
            previous_messages_stack=previous_messages_stack,
        )

    def chat(
        self,
        input_text: str,
        user_agent: Optional[UserAgent] = None,
        previous_messages_stack: Optional[PreviousMessagesStack] = None,
    ) -> Optional[str]:
        return self._processor.chat(
            input_text=input_text,
            user_agent=user_agent,
            previous_messages_stack=previous_messages_stack,
        )

    def remember(
        self,
        input_text: str,
        user_agent: Optional[UserAgent] = None,
        previous_messages_stack: Optional[PreviousMessagesStack] = None,
    ) -> Optional[str]:
        return self._processor.remember(
            input_text=input_text,
            user_agent=user_agent,
            previous_messages_stack=previous_messages_stack,
        )

    def search(
        self,
        input_text: str,
        user_agent: Optional[UserAgent] = None,
        previous_messages_stack: Optional[PreviousMessagesStack] = None,
        synthesized_text_type: Optional[SynthesizedTextType] = None,
    ) -> Optional[str]:
        return self._processor.search(
            input_text=input_text,
            user_agent=user_agent,
            previous_messages_stack=previous_messages_stack,
            synthesized_text_type=synthesized_text_type,
        )

    def generate_background_info(
        self,
        input_text: str,
        user_agent: Optional[UserAgent] = None,
        previous_messages_stack: Optional[PreviousMessagesStack] = None,
    ) -> str:
        return self._processor.generate_background_info(
            input_text=input_text,
            user_agent=user_agent,
            previous_messages_stack=previous_messages_stack,
        )

    def get_background_info(
        self,
        input_text: str,
        user_agent: Optional[UserAgent] = None,
        previous_messages_stack: Optional[PreviousMessagesStack] = None,
    ) -> str:
        return self._processor.get_background_info(
            input_text=input_text,
            user_agent=user_agent,
            previous_messages_stack=previous_messages_stack,
        )


DeepThinker = DeepthinkEngine
Thinker = DeepthinkEngine
