from typing import Optional, List
from datetime import datetime
import uuid
from analogai.foundation.extensions.conversation.repositories import ConversationRepository
from analogai.foundation.extensions.conversation.conversation import Conversation
from analogai.foundation.extensions.conversation.turn import Turn
from analogai.foundation.modules.user.user import User
from analogai.foundation.modules.agent.agent import Agent
from analogai.foundation.common.logging.app_logger import app_logger
from typeguard import typechecked


class ConversationService:
    def __init__(self, conversation_repository: ConversationRepository):
        self.repository = conversation_repository

    @typechecked
    def start_conversation(self, user_id: str, agent_id: str) -> Conversation:
        conversation = self.repository.create_conversation(user_id, agent_id)
        app_logger.debug(f"Created Conversation: {conversation.id}")
        return conversation

    @typechecked
    def add_turn(
        self,
        conversation_id: str,
        user_id: str,
        agent_id: str,
        user_message: str,
        agent_response: str,
    ) -> Turn:
        turn_id = str(uuid.uuid4())
        turn = Turn(
            id=turn_id,
            user_id=user_id,
            agent_id=agent_id,
            user_message=user_message,
            agent_response=agent_response,
            timestamp=datetime.now(),
        )

        self.repository.add_turn(conversation_id, turn)
        app_logger.debug(f"Added Turn to Conversation (turn_id: {turn.id}, conversation_id: {conversation_id})")
        return turn

    @typechecked
    def find(self, conversation_id: str) -> Optional[Conversation]:
        result = self.repository.find_by_id(conversation_id)
        if result:
            app_logger.debug(f"Found Conversation (conversation_id: {result.id})")
        else:
            app_logger.debug(f"Conversation not found: id={conversation_id}")
        return result

    @typechecked
    def get_conversations_by_agent_id(self, agent_id: str, page: int = 1, page_size: int = 10) -> List[Conversation]:
        return self.repository.find_by_agent(agent_id, page, page_size)

    @typechecked
    def delete_conversation(self, conversation_id: str) -> bool:
        success = self.repository.delete_conversation(conversation_id)
        if success:
            app_logger.debug(f"Deleted Conversation {conversation_id}")
        return success

    @typechecked
    def get_latest_conversation(self, user_id: str, agent_id: str) -> Optional[Conversation]:
        result = self.repository.find_latest_by_user_and_agent(user_id, agent_id)
        if result:
            app_logger.debug(f"Found latest Conversation (conversation_id: {result.id})")
        else:
            app_logger.debug(f"Latest conversation not found")
        return result

    @typechecked
    def ensure_conversation_exists(self, user_id: str, agent_id: str) -> Conversation:
        existing_conversation = self.repository.find_latest_by_user_and_agent(user_id, agent_id)
        if existing_conversation:
            app_logger.debug(f"Found existing Conversation (conversation_id: {existing_conversation.id})")
            return existing_conversation

        conversation = self.repository.create_conversation(user_id, agent_id)
        app_logger.debug(f"Created Conversation (conversation_id: {conversation.id})")
        return conversation
