# services/chat_service.py

from fastapi import UploadFile, HTTPException
from typing import Optional
import sys
import os
import time
import io
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from core import MessageType, AppConfig
from repositories import StorageRepository
from services.response_manager import ResponseManager
from services.openai_service import OpenAIService
from services.agent_service import AgentService
from services.segmentation_service import LanguageSegmentationService

class ChatService:
    def __init__(self, storage_repo: StorageRepository, response_manager: ResponseManager, 
                 config: AppConfig, openai_service: OpenAIService, agent_service: AgentService, segmentation_service: LanguageSegmentationService):
        from handlers import AudioMessageHandler, TextMessageHandler
        
        self.storage_repo = storage_repo
        self.response_manager = response_manager
        self.config = config
        self.openai_service = openai_service
        self.agent_service = agent_service
        self.segmentation_service = segmentation_service
        
        self.handlers = {
            MessageType.AUDIO: AudioMessageHandler(storage_repo, config.minio_bucket, openai_service),
            MessageType.TEXT: TextMessageHandler()
        }

    def process_message(self, student_id: str, file: Optional[UploadFile] = None, text: Optional[str] = None, game_context: Optional[str] = None):
        """Process message and generate text and audio response."""
        try:
            if file and file.filename:
                # Assuming handle method reads the file content
                file_content = file.file.read()
                user_message = self.handlers[MessageType.AUDIO].openai_service.transcribe_audio(file_content, file.filename)
            elif text:
                user_message = text
            else:
                raise HTTPException(status_code=400, detail="No text or audio file provided.")

            final_message_for_agent = user_message
            if game_context:
                print(f"Game context provided: {game_context}")
                final_message_for_agent = f"game context: {game_context}\nuser query: {user_message}"
            
            agent_response_text = self.agent_service.generate_response(
                user_message=final_message_for_agent,
                student_id=student_id,
            )

            audio_data = self._generate_and_upload_audio(agent_response_text, student_id)
            

            self.response_manager.store_response(
                student_id=student_id,
                text=agent_response_text,
                audio_filepath=audio_data.get("filepath"),
                audio_bytes=audio_data.get("bytes")
            )

            print(f"Generated response for student {student_id}: {agent_response_text[:100]}...")
            
            return {
                "status": "success",
                "message": "Message processed and agent response ready",
                "student_id": student_id,
                "agent_response": agent_response_text,
                "audio_filepath": audio_data.get("filepath")
            }
            
        except Exception as e:
            print(f"Error processing message for student {student_id}: {e}")
            raise HTTPException(status_code=500, detail=f"Failed to process message: {str(e)}")

    def _generate_and_upload_audio(self, text: str, student_id: str) -> dict:
        """
        Segments mixed-language text and generates TTS audio, then uploads to MinIO.
        """
        try:
            segments = self.segmentation_service.segment_text(text)
            audio_bytes = self.agent_service.tts_service.generate_speech_from_sequence(segments)

            file_extension = "wav"
            timestamp = int(time.time())
            filename = f"agent_response_{timestamp}_{student_id}.{file_extension}"
            minio_file_path = f"audio/{filename}"

            self.storage_repo.upload_file(
                file_obj=io.BytesIO(audio_bytes),
                bucket=self.config.minio_bucket,
                file_path=minio_file_path
            )
            
            full_url = self.storage_repo.get_file_url(
                bucket=self.config.minio_bucket,
                file_path=minio_file_path,
                expires=3600  # 1 hour
            )
            print(f"Successfully generated and uploaded TTS audio: {filename}")
            return {"bytes": audio_bytes, "filepath": full_url}

        except Exception as e:
            print(f"Error in _generate_and_upload_audio: {e}")
            return {"bytes": None, "filepath": None}