import transformers 
import torch
from .logger import logger
from .audio_utils import AudioUtils
import platform


# Disable whisper log data
transformers.logging.set_verbosity_error()

class WhisperLocal:
    def __init__(self, model_name="openai/whisper-tiny", language='ru', device='auto'):
        self.model_name = model_name
        self.language = language
        self.device = device
        self.transcriber = None
        self._load_model()

    def _get_device(self):
        """detecting audio devices"""
        if self.device != 'auto':
            return self.device
            
        # checking platform
        # using gpu: mps (Apple Silicon) or cuda
        if platform.system() == "Darwin" and torch.backends.mps.is_available():
            logger.info("Using MPS (Apple Silicon) device")
            return "mps"
        
        if torch.cuda.is_available():
            logger.info("Using CUDA device")
            return "cuda"
        
        # using cpu if gpu is not available
        logger.info("Using CPU device")
        return "cpu"
    
    def _load_model(self):
        """load Whisper model"""
        try:
            logger.info(f"Loading Whisper model: {self.model_name}")
            
            device = self._get_device()
            
            self.transcriber = transformers.pipeline(
                "automatic-speech-recognition",
                model=self.model_name,
                language=self.language,
                device=device,
                return_timestamps=True,
            )
            logger.info(f"Whisper model loaded successfully on {device}")
        except Exception as e:
            logger.error(f"Error loading Whisper model: {e}")
            raise
    
    def _transcribe_chunk(self, chunk_data, sample_rate):
        """translate one chunk"""
        try:
            tmp_file_path = AudioUtils.save_audio_to_temp(chunk_data, sample_rate)
            if not tmp_file_path:
                return ""
            
            result = self.transcriber(
                tmp_file_path,
                return_timestamps=True,  
                generate_kwargs={"language": self.language, "task": "transcribe"}
            )
            
            if isinstance(result, dict):
                text = result.get("text", "").strip()
            else:
                text = str(result).strip()
            
            AudioUtils.cleanup_temp_file(tmp_file_path)
            
            logger.info(f"Chunk result: '{text}'")
            return text
        except Exception as e:
            logger.error(f"Error transcribing chunk: {e}")
            return ""
        
    def _split_audio_into_chunks(self, audio_data, sample_rate):
        """splitting audio into chunks by 10 seconds and 2 seconds overlap"""
        chunk_size_samples = 10 * sample_rate  
        overlap_samples = 2 * sample_rate      
        step_samples = chunk_size_samples - overlap_samples
        
        chunks = []
        start = 0
        
        while start < len(audio_data):
            end = min(start + chunk_size_samples, len(audio_data))
            chunk = audio_data[start:end]
            
            # adding chunk if it is big enough 
            if len(chunk) > sample_rate * 2:  # 2 seconds
                chunks.append(chunk)
            
            if end >= len(audio_data):
                break
                
            start += step_samples
        
        logger.info(f"Split audio into {len(chunks)} chunks")
        return chunks
   
    def transcribe_file(self, file_path, sample_rate=16000):
        """translate audio file by chunks splitting"""
        try:
            logger.info(f"Transcribing file with chunking: {file_path}")

            result = AudioUtils.read_audio_file(file_path)
            if result is None:
                logger.error("Failed to read audio file")
                return ""
            
            sample_rate, audio_data = result
            
            # splitting - теперь передаем audio_data вместо file_path
            chunks = self._split_audio_into_chunks(audio_data, sample_rate)
            
            if not chunks:
                logger.warning("No chunks created from audio")
                return ""
            
            # translate chunk by chunk
            all_texts = []
            for i, chunk in enumerate(chunks):
                logger.info(f"Transcribing chunk {i+1}/{len(chunks)}")
                text = self._transcribe_chunk(chunk, sample_rate)
                if text and text.strip():
                    all_texts.append(text.strip())
            
            # gluing the results
            final_text = " ".join(all_texts)
            logger.info(f"Final transcription: {final_text}")
                
            return final_text
            
        except Exception as e:
            logger.error(f"Error transcribing with chunking: {e}")
            return ""

    def transcribe_audio_data(self, audio_data, sample_rate=16000):
        """save audio to the temp file and translating it by calling transcribe_file()"""
        try:
            tmp_file_path = AudioUtils.save_audio_to_temp(audio_data, sample_rate)
            if not tmp_file_path:
                return ""
            
            text = self.transcribe_file(tmp_file_path)
            AudioUtils.cleanup_temp_file(tmp_file_path)
            return text
        except Exception as e:
            logger.error(f"Error transcribing audio data: {e}")
            return ""