import queue
import sounddevice as sd
import json
import sys
from vosk import Model, KaldiRecognizer
from http.server import HTTPServer, BaseHTTPRequestHandler
import threading

# =========================
# CONFIG
# =========================
MODEL_PATH = "C:/VoiceEA/vosk-model"
WAKE_PHRASES = ["hello trader", "okay trader", "hey trader"]
PORT = 8080

GRAMMAR = [
    "hello trader", "okay trader", "hey trader",
    "buy euro usd", "sell euro usd", "buy gold", "sell gold",
    "close all", "close trade", "status", "exit"
]

# =========================
# GLOBAL COMMAND STORE
# =========================
latest_command = ""

# =========================
# VOSK SETUP
# =========================
print("🔄 Loading Vosk model...")
try:
    model = Model(MODEL_PATH)
except Exception as e:
    print(f"❌ Model loading failed: {e}")
    sys.exit(1)

recognizer = KaldiRecognizer(model, 16000)
recognizer.SetGrammar(json.dumps(GRAMMAR))

# =========================
# AUDIO STREAM
# =========================
q = queue.Queue()

def callback(indata, frames, time, status):
    if status:
        print(status, file=sys.stderr)
    q.put(bytes(indata))

def wake_detected(text):
    return any(phrase in text for phrase in WAKE_PHRASES)

def extract_command(text):
    for phrase in WAKE_PHRASES:
        if phrase in text:
            return text.replace(phrase, "").strip()
    return text.strip()

def parse_command(text):
    words = text.lower().split()
    action = None
    symbol = None
    if "buy" in words:
        action = "BUY"
    elif "sell" in words:
        action = "SELL"
    elif "close" in words:
        if "all" in words:
            return "CLOSE_ALL"
        return "CLOSE"
    if any(w in words for w in ["euro", "eur", "usd", "eu", "eurodollar"]):
        symbol = "EURUSD"
    elif any(w in words for w in ["gold", "xau"]):
        symbol = "XAUUSD"
    if not action:
        return None
    if action in ["BUY", "SELL"] and not symbol:
        print("⚠️ No valid symbol detected")
        return None
    if action in ["BUY", "SELL"]:
        return f"{action}_{symbol}"
    return action

def audio_loop():
    global latest_command
    listening_for_command = False
    with sd.RawInputStream(samplerate=16000, blocksize=8000, dtype='int16', channels=1, callback=callback):
        while True:
            data = q.get()
            if recognizer.AcceptWaveform(data):
                result = json.loads(recognizer.Result())
                text = result.get("text", "").lower().strip()
                if not text or len(text.split()) < 2:
                    continue
                print(f"🗣 You said: {text}")
                if not listening_for_command:
                    if wake_detected(text):
                        print("👂 Wake phrase detected. Listening for command...")
                        listening_for_command = True
                    continue
                raw_command = extract_command(text)
                parsed_command = parse_command(raw_command)
                if not parsed_command:
                    print("❌ Invalid command")
                    listening_for_command = False
                    continue
                print(f"✅ Parsed Command: {parsed_command}")
                latest_command = parsed_command
                listening_for_command = False
            else:
                pass

# =========================
# HTTP SERVER HANDLER
# =========================
class CommandHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        global latest_command
        if self.path == "/command":
            self.send_response(200)
            self.send_header("Content-Type", "text/plain")
            self.end_headers()
            self.wfile.write(latest_command.encode("ascii"))
            latest_command = ""  # clear after read
        else:
            self.send_response(404)
            self.end_headers()
    
    def log_message(self, format, *args):
        pass  # suppress HTTP logs

def start_server():
    server = HTTPServer(("127.0.0.1", PORT), CommandHandler)
    print(f"🌐 HTTP server running on http://127.0.0.1:{PORT}")
    server.serve_forever()

# =========================
# MAIN
# =========================
if __name__ == "__main__":
    threading.Thread(target=audio_loop, daemon=True).start()
    start_server()