import os
import time
import tempfile
import io
from typing import Optional, List, Dict
from fastapi import HTTPException
from openai import OpenAI
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from core import Models
from services.tts.base_tts_service import BaseTTSService


class OpenAIService(BaseTTSService):
    """Service class for handling OpenAI API operations (TTS, Whisper, Embeddings)"""
    
    def __init__(self):
        self.api_key = os.getenv("OPENAI_API_KEY")
        if not self.api_key:
            print("Warning: OPENAI_API_KEY not found. OpenAI services will be disabled.")
            self.client = None
        else:
            self.client = OpenAI(api_key=self.api_key)
    
    def is_available(self) -> bool:
        """Check if OpenAI service is available"""
        return self.client is not None
    
    # ------------------- Whisper -------------------
    def transcribe_audio(self, file_content: bytes, filename: str, language: Optional[str] = "ar") -> str:
        """Transcribe audio using OpenAI Whisper"""
        if not self.is_available():
            raise HTTPException(status_code=500, detail="OpenAI service not available")
        
        try:
            audio_file = io.BytesIO(file_content)
            audio_file.name = filename
            print(f"Transcribing audio: {filename}")
            
            transcript = self.client.audio.transcriptions.create(
                model=Models.transcription.value,
                file=audio_file,
                language=language if language else None
            )
            
            transcribed_text = transcript.text.strip()
            if not transcribed_text:
                raise ValueError("Empty transcription result")
            
            print(f"Transcription successful: {transcribed_text[:100]}...")
            return transcribed_text
            
        except Exception as e:
            print(f"Error during transcription: {e}")
            raise HTTPException(status_code=500, detail=f"Transcription failed: {str(e)}")
    
    # ------------------- TTS -------------------
    def generate_speech(self, text: str, language: str = "en") -> bytes:
        """Generate speech from text using OpenAI TTS. Returns raw audio bytes."""
        if not self.is_available():
            raise HTTPException(status_code=500, detail="OpenAI service not available")
        
        voice = "alloy"
        
        try:
            print(f"Generating TTS audio with OpenAI: {text[:50]}...")
            
            response = self.client.audio.speech.create(
                model=Models.tts,
                voice=voice,
                input=text,
                response_format="wav"
            )
            
            audio_bytes = response.content
            print("OpenAI TTS generation successful.")
            return audio_bytes
            
        except Exception as e:
            print(f"Error during OpenAI TTS generation: {e}")
            raise HTTPException(status_code=500, detail=f"OpenAI TTS generation failed: {str(e)}")
    
    def generate_speech_from_sequence(self, segments: List[Dict[str, str]]) -> bytes:
        """
        Fallback implementation for OpenAI. It combines the text from all
        segments and makes a single TTS call.
        """
        print("OpenAI provider: combining segments for a single TTS call.")
        full_text = " ".join([segment['text'] for segment in segments])
        
        # Just call the existing simple method
        return self.generate_speech(full_text)


    # ------------------- Embeddings -------------------
    def generate_embedding(self, text: str) -> List[float]:
        """
        Generate an embedding vector for input text.
        
        Args:
            text: Input string
            model: Embedding model (default: text-embedding-3-small)
        
        Returns:
            List[float]: Embedding vector
        """
        if not self.is_available():
            raise HTTPException(status_code=500, detail="OpenAI service not available")
        
        try:
            response = self.client.embeddings.create(
                model=Models.embedding,
                input=text
            )
            embedding = response.data[0].embedding
            if not embedding:
                raise ValueError("Empty embedding generated")
            
            return embedding
        except Exception as e:
            print(f"Error during embedding generation: {e}")
            raise HTTPException(status_code=500, detail=f"Embedding generation failed: {str(e)}")
    
    # ------------------- Utils -------------------
    def cleanup_temp_file(self, file_path: str) -> None:
        """Clean up temporary file"""
        if file_path and os.path.exists(file_path):
            try:
                os.unlink(file_path)
                print(f"Cleaned up temporary file: {file_path}")
            except Exception as e:
                print(f"Warning: Could not clean up temp file {file_path}: {e}")


    