from crewai.tools import BaseTool
from pydantic import BaseModel, Field
from typing import Type
import time
import sounddevice as sd
import numpy as np
import uuid
import os
from scipy.io.wavfile import write
import whisper


class LiveWhisperSTTTool(BaseTool):
    name: str = "Live Whisper STT Tool"
    description: str = "Records user's voice from microphone until silence is detected, then transcribes using Whisper."
    args_schema: Type[BaseModel] = type("EmptyInput", (BaseModel,), {})
    def _run(self) -> str:
        try:
            silence_duration = 3
 
            print(f"Speak now. Recording will stop after {silence_duration} seconds of silence...")
 
            samplerate = 16000
            blocksize = 1024
            silence_threshold = 0.01
            # silence_duration = 6
            max_record_seconds = 60
 
            audio_buffer = []
            last_voice_time = time.time()
            start_time = time.time()
 
            with sd.InputStream(samplerate=samplerate, channels=1, blocksize=blocksize) as stream:
                while True:
                    block, _ = stream.read(blocksize)
                    volume = np.linalg.norm(block)
                    audio_buffer.append(block.copy())
 
                    current_time = time.time()
                    if volume > silence_threshold:
                        last_voice_time = current_time
 
                    if current_time - last_voice_time > silence_duration:
                        print("🔕 Silence detected. Stopping recording.")
                        break
 
                    if current_time - start_time > max_record_seconds:
                        print("⏱️ Max recording time reached. Stopping.")
                        break
 
            audio_data = np.concatenate(audio_buffer, axis=0)
 
            # Save permanently instead of using tempfile
            filename = f"user_answer_{uuid.uuid4().hex[:8]}.wav"
            filepath = os.path.join("recordings", filename)
            os.makedirs("recordings", exist_ok=True)
            write(filepath, samplerate, audio_data)
 
            model = whisper.load_model("base")
            result = model.transcribe(filepath)
 
            return {
                "transcription": result["text"],
                "audio_file": filepath
            }
        
 
        except Exception as e:
            return {
                "transcription": f"An error occurred during transcription: {e}",
                "audio_file": None
            }
 