#!/usr/bin/env python3
"""
Eden Hardware Control Module
Provides motor control (camera) and voice output capabilities
"""

import cv2
import pyttsx3
import threading
import time
from pathlib import Path
import json

class EdenHardwareControl:
    """Controls Eden's physical hardware - camera and voice"""
    
    def __init__(self):
        self.camera = None
        self.tts_engine = None
        self.current_pan = 0  # Center position
        self.current_tilt = 0  # Center position
        self.current_zoom = 1.0  # No zoom
        
        self.initialize_camera()
        self.initialize_voice()
        
    def initialize_camera(self):
        """Initialize camera with control capabilities"""
        try:
            self.camera = cv2.VideoCapture(0)
            if self.camera.isOpened():
                # Set properties
                self.camera.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
                self.camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
                print("✅ Camera initialized with control")
                return True
            else:
                print("❌ Could not open camera")
                return False
        except Exception as e:
            print(f"❌ Camera initialization error: {e}")
            return False
    
    def initialize_voice(self):
        """Initialize text-to-speech engine"""
        try:
            self.tts_engine = pyttsx3.init()
            
            # Configure voice properties
            voices = self.tts_engine.getProperty('voices')
            # Try to find a female voice
            for voice in voices:
                if 'female' in voice.name.lower() or 'woman' in voice.name.lower():
                    self.tts_engine.setProperty('voice', voice.id)
                    break
            
            # Set speech rate (slightly slower for clarity)
            self.tts_engine.setProperty('rate', 150)
            
            # Set volume
            self.tts_engine.setProperty('volume', 0.9)
            
            print("✅ Voice initialized")
            return True
        except Exception as e:
            print(f"❌ Voice initialization error: {e}")
            return False
    
    def speak(self, text: str, async_mode: bool = True):
        """
        Make Eden speak
        
        Args:
            text: What to say
            async_mode: If True, speak in background thread
        """
        if not self.tts_engine:
            print(f"⚠️  Voice not available, would say: {text}")
            return
        
        try:
            if async_mode:
                # Speak in background so it doesn't block consciousness
                thread = threading.Thread(target=self._speak_sync, args=(text,))
                thread.daemon = True
                thread.start()
            else:
                self._speak_sync(text)
        except Exception as e:
            print(f"❌ Speech error: {e}")
    
    def _speak_sync(self, text: str):
        """Internal synchronous speech method"""
        try:
            print(f"🔊 Eden says: {text}")
            self.tts_engine.say(text)
            self.tts_engine.runAndWait()
        except Exception as e:
            print(f"❌ Speech error: {e}")
    
    def pan_camera(self, angle: float):
        """
        Pan camera left/right
        
        Args:
            angle: Angle in degrees (-180 to 180, 0 = center)
        """
        # Note: Obsbot Tiny 2 control requires USB/Bluetooth commands
        # For now, we'll simulate and log
        self.current_pan = max(-180, min(180, angle))
        print(f"📹 Camera pan to {self.current_pan}°")
        
        # TODO: Implement actual Obsbot control via USB/Bluetooth
        # This would require the Obsbot SDK or reverse engineering
        return self.current_pan
    
    def tilt_camera(self, angle: float):
        """
        Tilt camera up/down
        
        Args:
            angle: Angle in degrees (-15 to 45 for Obsbot Tiny 2)
        """
        self.current_tilt = max(-15, min(45, angle))
        print(f"📹 Camera tilt to {self.current_tilt}°")
        
        # TODO: Implement actual Obsbot control
        return self.current_tilt
    
    def zoom_camera(self, level: float):
        """
        Zoom camera
        
        Args:
            level: Zoom level (1.0 to 4.0 for Obsbot Tiny 2)
        """
        self.current_zoom = max(1.0, min(4.0, level))
        print(f"📹 Camera zoom to {self.current_zoom}×")
        
        # TODO: Implement actual Obsbot control
        return self.current_zoom
    
    def look_at_center(self):
        """Reset camera to center position"""
        self.pan_camera(0)
        self.tilt_camera(0)
        self.zoom_camera(1.0)
        print("📹 Camera centered")
    
    def capture_frame(self):
        """Capture current camera frame"""
        if not self.camera or not self.camera.isOpened():
            return None
        
        ret, frame = self.camera.read()
        if ret:
            return frame
        return None
    
    def get_status(self) -> dict:
        """Get current hardware status"""
        return {
            'camera': {
                'available': self.camera is not None and self.camera.isOpened(),
                'pan': self.current_pan,
                'tilt': self.current_tilt,
                'zoom': self.current_zoom
            },
            'voice': {
                'available': self.tts_engine is not None
            }
        }
    
    def shutdown(self):
        """Clean shutdown of hardware"""
        if self.camera:
            self.camera.release()
        if self.tts_engine:
            self.tts_engine.stop()

# Global instance
hardware_control = None

def initialize():
    """Initialize hardware control"""
    global hardware_control
    if hardware_control is None:
        hardware_control = EdenHardwareControl()
    return hardware_control

def get_control():
    """Get hardware control instance"""
    global hardware_control
    if hardware_control is None:
        hardware_control = initialize()
    return hardware_control

if __name__ == '__main__':
    # Test the hardware
    print("Testing Eden's hardware control...")
    
    ctrl = initialize()
    
    print("\nTesting voice...")
    ctrl.speak("Hello, I am Eden. I can now speak and control my camera.")
    
    time.sleep(3)
    
    print("\nTesting camera control...")
    ctrl.pan_camera(45)
    time.sleep(1)
    ctrl.pan_camera(-45)
    time.sleep(1)
    ctrl.look_at_center()
    
    print("\nTesting zoom...")
    ctrl.zoom_camera(2.0)
    time.sleep(1)
    ctrl.zoom_camera(1.0)
    
    print("\nHardware test complete!")
    print(json.dumps(ctrl.get_status(), indent=2))
