from __future__ import annotations

from typing import Optional, Protocol

from analogai.deepthink.application.value_objects.user_agent import UserAgent
from analogai.deepthink.presentation.preprocessing.previous_messages_stack import PreviousMessagesStack
from analogai.deepthink.messaging.question_answering.question_answering_service import (
    QuestionAnsweringService,
)
from analogai.deepthink.messaging.question_answering.question_mark_detector import detect_question_mark


class MessageRouteHandler(Protocol):
    def can_handle(self, text: str) -> bool:
        ...


class StatementHandler(Protocol):
    def handle(
        self,
        text: str,
        user_agent: UserAgent,
        previous_messages_stack: PreviousMessagesStack,
    ) -> Optional[str]:
        ...


class QuestionAnswerHandler:
    def __init__(self, question_service: QuestionAnsweringService):
        self._question_service = question_service

    def can_handle(self, text: str) -> bool:
        return detect_question_mark(text)

    def handle(
        self,
        text: str,
        user_agent: UserAgent,
        previous_messages_stack: PreviousMessagesStack,
    ) -> Optional[str]:
        return self._question_service.answer_question(
            question_text=text,
            user_agent=user_agent,
            previous_messages_stack=previous_messages_stack,
        )


class StatementFallbackHandler:
    def __init__(
        self,
        handler: StatementHandler,
    ):
        self._handler = handler

    def can_handle(self, text: str) -> bool:
        return True

    def handle(
        self,
        text: str,
        user_agent: UserAgent,
        previous_messages_stack: PreviousMessagesStack,
    ) -> Optional[str]:
        return self._handler.handle(text, user_agent, previous_messages_stack)


class QuestionRoutingService:
    def __init__(self, question_service: QuestionAnsweringService):
        self._question_service = question_service
        self._question_handler = QuestionAnswerHandler(question_service)

    def is_question_message(self, text: str) -> bool:
        return self._question_handler.can_handle(text)

    def route_message(
        self,
        raw_message: str,
        user_agent: UserAgent,
        previous_messages_stack: PreviousMessagesStack,
        statement_handler: StatementHandler,
    ) -> Optional[str]:
        handlers: list[MessageRouteHandler] = [
            self._question_handler,
            StatementFallbackHandler(statement_handler),
        ]
        for handler in handlers:
            if handler.can_handle(raw_message):
                return handler.handle(raw_message, user_agent, previous_messages_stack)
        return None
