from typing import List, Dict, Any, Optional
from datetime import datetime
import boto3
import json
from ..models.chat import Message, ChatHistory, ChatRequest, ChatResponse
from ..core.config import settings

class ChatService:
    def __init__(self):
        self.bedrock = boto3.client(
            service_name='bedrock-runtime',
            region_name=settings.AWS_REGION,
            aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
            aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY
        )
        self.chat_histories: Dict[str, ChatHistory] = {}

    def get_chat_history(self, user_id: str, event_id: Optional[str] = None) -> ChatHistory:
        """Obtiene el historial de chat para un usuario y evento específicos"""
        key = f"{user_id}_{event_id}" if event_id else user_id
        if key not in self.chat_histories:
            self.chat_histories[key] = ChatHistory(
                user_id=user_id,
                event_id=event_id
            )
        return self.chat_histories[key]

    def add_message(self, user_id: str, event_id: Optional[str], message: str, role: str = "user"):
        """Añade un mensaje al historial de chat"""
        chat_history = self.get_chat_history(user_id, event_id)
        chat_history.messages.append(Message(
            role=role,
            content=message
        ))

    def process_message(self, request: ChatRequest) -> ChatResponse:
        """Procesa un mensaje del usuario y genera una respuesta"""
        # Añadir mensaje del usuario al historial
        self.add_message(request.user_id, request.event_id, request.message)

        # Preparar el contexto para el modelo
        chat_history = self.get_chat_history(request.user_id, request.event_id)
        context = self._prepare_context(chat_history, request.context)

        # Generar respuesta usando Bedrock
        response = self._generate_response(context)

        # Añadir respuesta del asistente al historial
        self.add_message(request.user_id, request.event_id, response["message"], "assistant")

        return ChatResponse(
            response=response["message"],
            services=response.get("services", []),
            event_updates=response.get("event_updates"),
            suggest_confirmation=response.get("suggest_confirmation", False)
        )

    def _prepare_context(self, chat_history: ChatHistory, additional_context: List[str]) -> str:
        """Prepara el contexto para el modelo"""
        context = []
        
        # Añadir historial de chat
        for message in chat_history.messages[-5:]:  # Últimos 5 mensajes
            context.append(f"{message.role}: {message.content}")

        # Añadir contexto adicional
        if additional_context:
            context.extend(additional_context)

        return "\n".join(context)

    def _generate_response(self, context: str) -> Dict[str, Any]:
        """Genera una respuesta usando AWS Bedrock"""
        prompt = f"""Eres un asistente de planificación de eventos. 
        Basándote en la siguiente conversación, proporciona una respuesta útil y relevante.
        
        Conversación:
        {context}
        
        Responde de manera natural y conversacional, manteniendo el contexto de la conversación."""

        request_body = {
            "prompt": prompt,
            "max_tokens_to_sample": settings.BEDROCK_MAX_TOKENS,
            "temperature": settings.BEDROCK_TEMPERATURE,
            "stop_sequences": ["\n\n"]
        }

        response = self.bedrock.invoke_model(
            modelId=settings.BEDROCK_MODEL_ID,
            body=json.dumps(request_body)
        )

        response_body = json.loads(response.get('body').read())
        response_text = response_body.get('completion', '')

        # Procesar la respuesta para extraer servicios y actualizaciones
        services = self._extract_services(response_text)
        event_updates = self._extract_event_updates(response_text)
        suggest_confirmation = self._should_suggest_confirmation(response_text)

        return {
            "message": response_text,
            "services": services,
            "event_updates": event_updates,
            "suggest_confirmation": suggest_confirmation
        }

    def _extract_services(self, response: str) -> List[Dict[str, Any]]:
        """Extrae información de servicios de la respuesta"""
        # Implementar lógica para extraer servicios
        return []

    def _extract_event_updates(self, response: str) -> Optional[Dict[str, Any]]:
        """Extrae actualizaciones de evento de la respuesta"""
        # Implementar lógica para extraer actualizaciones
        return None

    def _should_suggest_confirmation(self, response: str) -> bool:
        """Determina si se debe sugerir confirmación"""
        # Implementar lógica para determinar si sugerir confirmación
        return False 