"""
Screen cast management routes for the web dashboard
"""

from flask import Blueprint, request, jsonify, render_template, flash, redirect, url_for
from flask_login import login_required
import logging

logger = logging.getLogger(__name__)

# Create blueprint
screen_cast_bp = Blueprint('screen_cast', __name__)

@screen_cast_bp.route('/screen_cast')
@login_required
def screen_cast_dashboard():
    """Screen cast management dashboard"""
    try:
        return render_template('dashboard/screen_cast.html')
    except Exception as e:
        logger.error(f"Error loading screen cast dashboard: {e}")
        flash("Error loading screen cast dashboard", "error")
        return redirect(url_for('main.index'))

@screen_cast_bp.route('/api/screen_cast/status')
@login_required
def get_screen_cast_status():
    """Get current screen cast status"""
    try:
        from flask import g
        
        # Get status from the screen cast component through message bus
        if hasattr(g, 'message_bus'):
            try:
                # Try to get the actual component instance from the thread manager
                # This is a workaround since we don't have sync request/response in message bus
                from flask import g
                
                # Try to access the application instance
                app_instance = getattr(g, 'main_app', None)
                if app_instance and hasattr(app_instance, 'screen_cast') and app_instance.screen_cast:
                    # Get real status from the component
                    real_status = app_instance.screen_cast.get_status()
                    
                    # Transform to web-compatible format
                    status = {
                        "enabled": True,
                        "capture_active": real_status.get("capture_active", False),
                        "streaming_active": real_status.get("streaming_active", False),
                        "chromecast_connected": real_status.get("chromecast_connected", False),
                        "stream_port": real_status.get("stream_port", 8000),
                        "chromecast_name": app_instance.screen_cast.chromecast_name,
                        "chromecast_device": real_status.get("chromecast_device", "Unknown"),
                        "last_error": real_status.get("last_error"),
                        "local_ip": real_status.get("local_ip", "127.0.0.1"),
                        "stream_file_exists": real_status.get("stream_file_exists", False)
                    }
                    return jsonify({"success": True, "status": status})
                else:
                    # Fallback to basic status with network IP detection
                    import socket
                    
                    def get_local_ip():
                        try:
                            with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
                                s.connect(("8.8.8.8", 80))
                                return s.getsockname()[0]
                        except:
                            return "127.0.0.1"
                    
                    local_ip = get_local_ip()
                    
                    status = {
                        "enabled": True,
                        "capture_active": False,
                        "streaming_active": False,
                        "chromecast_connected": False,
                        "stream_port": 8000,
                        "chromecast_name": None,
                        "last_error": "Component not directly accessible",
                        "local_ip": local_ip
                    }
                    return jsonify({"success": True, "status": status})
                
            except Exception as e:
                logger.debug(f"Could not communicate with screen cast component: {e}")
                # Return disabled status
                status = {
                    "enabled": False,
                    "capture_active": False,
                    "streaming_active": False,
                    "chromecast_connected": False,
                    "stream_port": 8000,
                    "chromecast_name": None,
                    "last_error": "Screen cast component not available",
                    "local_ip": "127.0.0.1"
                }
                return jsonify({"success": True, "status": status})
        else:
            return jsonify({"success": False, "error": "Message bus not available"}), 500
            
    except Exception as e:
        logger.error(f"Error getting screen cast status: {e}")
        return jsonify({"success": False, "error": str(e)}), 500

@screen_cast_bp.route('/api/screen_cast/start_capture', methods=['POST'])
@login_required
def start_capture():
    """Start screen capture"""
    try:
        from flask import g
        data = request.get_json() or {}
        resolution = data.get('resolution', '1280x720')
        framerate = data.get('framerate', 15)
        
        logger.info(f"Web request to start screen capture: {resolution} @ {framerate}fps")
        
        # Send message to screen cast component to start capture
        if hasattr(g, 'message_bus'):
            try:
                from ..core.message_bus import Message, MessageType
                import uuid
                
                # Create message to start capture
                start_message = Message(
                    type=MessageType.WEB_ACTION,  # Use WEB_ACTION for commands from web
                    sender="web_dashboard",
                    recipient="screen_cast",
                    data={
                        "action": "start_capture",
                        "resolution": resolution,
                        "framerate": framerate
                    },
                    correlation_id=str(uuid.uuid4())
                )
                
                g.message_bus.publish(start_message)
                logger.info(f"Sent start capture message to screen cast component")
                
                return jsonify({
                    "success": True,
                    "message": f"Screen capture start command sent ({resolution} @ {framerate}fps)"
                })
                
            except Exception as e:
                logger.error(f"Failed to send message to screen cast component: {e}")
                return jsonify({
                    "success": False,
                    "error": f"Failed to communicate with screen cast component: {str(e)}"
                })
        else:
            return jsonify({
                "success": False,
                "error": "Message bus not available"
            })
        
    except Exception as e:
        logger.error(f"Error starting capture: {e}")
        return jsonify({"success": False, "error": str(e)}), 500

@screen_cast_bp.route('/api/screen_cast/stop_capture', methods=['POST'])
@login_required
def stop_capture():
    """Stop screen capture"""
    try:
        from flask import g
        logger.info("Web request to stop screen capture")
        
        # Send message to screen cast component to stop capture
        if hasattr(g, 'message_bus'):
            try:
                from ..core.message_bus import Message, MessageType
                import uuid
                
                stop_message = Message(
                    type=MessageType.WEB_ACTION,
                    sender="web_dashboard",
                    recipient="screen_cast",
                    data={"action": "stop_capture"},
                    correlation_id=str(uuid.uuid4())
                )
                
                g.message_bus.publish(stop_message)
                logger.info("Sent stop capture message to screen cast component")
                
                return jsonify({
                    "success": True,
                    "message": "Screen capture stop command sent"
                })
                
            except Exception as e:
                logger.error(f"Failed to send message to screen cast component: {e}")
                return jsonify({
                    "success": False,
                    "error": f"Failed to communicate with screen cast component: {str(e)}"
                })
        else:
            return jsonify({
                "success": False,
                "error": "Message bus not available"
            })
        
    except Exception as e:
        logger.error(f"Error stopping capture: {e}")
        return jsonify({"success": False, "error": str(e)}), 500

@screen_cast_bp.route('/api/screen_cast/start_streaming', methods=['POST'])
@login_required
def start_streaming():
    """Start Chromecast streaming"""
    try:
        from flask import g
        logger.info("Web request to start Chromecast streaming")
        
        # Send message to screen cast component to start streaming
        if hasattr(g, 'message_bus'):
            try:
                from ..core.message_bus import Message, MessageType
                import uuid
                
                streaming_message = Message(
                    type=MessageType.WEB_ACTION,
                    sender="web_dashboard",
                    recipient="screen_cast",
                    data={"action": "start_streaming"},
                    correlation_id=str(uuid.uuid4())
                )
                
                g.message_bus.publish(streaming_message)
                logger.info("Sent start streaming message to screen cast component")
                
                return jsonify({
                    "success": True,
                    "message": "Chromecast streaming start command sent"
                })
                
            except Exception as e:
                logger.error(f"Failed to send message to screen cast component: {e}")
                return jsonify({
                    "success": False,
                    "error": f"Failed to communicate with screen cast component: {str(e)}"
                })
        else:
            return jsonify({
                "success": False,
                "error": "Message bus not available"
            })
        
    except Exception as e:
        logger.error(f"Error starting streaming: {e}")
        return jsonify({"success": False, "error": str(e)}), 500

@screen_cast_bp.route('/api/screen_cast/stop_streaming', methods=['POST'])
@login_required
def stop_streaming():
    """Stop Chromecast streaming"""
    try:
        from flask import g
        logger.info("Web request to stop Chromecast streaming")
        
        # Send message to screen cast component to stop streaming
        if hasattr(g, 'message_bus'):
            try:
                from ..core.message_bus import Message, MessageType
                import uuid
                
                streaming_message = Message(
                    type=MessageType.WEB_ACTION,
                    sender="web_dashboard",
                    recipient="screen_cast",
                    data={"action": "stop_streaming"},
                    correlation_id=str(uuid.uuid4())
                )
                
                g.message_bus.publish(streaming_message)
                logger.info("Sent stop streaming message to screen cast component")
                
                return jsonify({
                    "success": True,
                    "message": "Chromecast streaming stop command sent"
                })
                
            except Exception as e:
                logger.error(f"Failed to send message to screen cast component: {e}")
                return jsonify({
                    "success": False,
                    "error": f"Failed to communicate with screen cast component: {str(e)}"
                })
        else:
            return jsonify({
                "success": False,
                "error": "Message bus not available"
            })
        
    except Exception as e:
        logger.error(f"Error stopping streaming: {e}")
        return jsonify({"success": False, "error": str(e)}), 500

@screen_cast_bp.route('/api/screen_cast/discover_chromecasts')
@login_required
def discover_chromecasts():
    """Discover available Chromecast devices"""
    try:
        import pychromecast
        import time
        
        logger.info("Starting Chromecast discovery...")
        
        # Discover all Chromecasts on the network
        chromecasts, browser = pychromecast.get_chromecasts(timeout=5)
        
        discovered_devices = []
        
        # Create a map of hosts to service info for better name resolution
        service_map = {}
        if 'services' in locals():
            for service in services:
                try:
                    if hasattr(service, 'host') and hasattr(service, 'friendly_name'):
                        service_map[service.host] = service.friendly_name
                    elif hasattr(service, 'services') and service.services:
                        # Parse service name from mDNS
                        for svc_name in service.services:
                            if '_googlecast._tcp' in svc_name:
                                # Extract friendly name from service name
                                friendly_name = svc_name.split('._googlecast._tcp')[0]
                                if hasattr(service, 'host'):
                                    service_map[service.host] = friendly_name
                except Exception as e:
                    logger.debug(f"Error parsing service info: {e}")
        
        for cast in chromecasts:
            try:
                # Get host and port from socket_client first
                host = getattr(cast.socket_client, 'host', 'Unknown') if hasattr(cast, 'socket_client') else 'Unknown'
                port = getattr(cast.socket_client, 'port', 8009) if hasattr(cast, 'socket_client') else 8009
                
                # Alternative: try uri property
                if host == 'Unknown' and hasattr(cast, 'uri'):
                    try:
                        host = cast.uri.split(':')[0]
                        port = int(cast.uri.split(':')[1]) if ':' in cast.uri else 8009
                    except:
                        pass
                
                # Try multiple approaches to get device name
                device_name = None
                device_type = "Chromecast"
                uuid = None
                manufacturer = "Google"
                model = "Unknown"
                
                # Method 1: Try to connect and get device info with longer timeout
                try:
                    cast.wait(timeout=8)  # Longer timeout for better connection
                    if hasattr(cast, 'device') and cast.device:
                        device_name = getattr(cast.device, 'friendly_name', None)
                        if hasattr(cast.device, 'cast_type') and cast.device.cast_type:
                            device_type = cast.device.cast_type.name
                        uuid = getattr(cast.device, 'uuid', None)
                        manufacturer = getattr(cast.device, 'manufacturer', 'Google')
                        model = getattr(cast.device, 'model_name', 'Unknown')
                        logger.debug(f"Got device info from cast.device: {device_name}")
                except Exception as e:
                    logger.debug(f"Method 1 failed: {e}")
                
                # Method 2: Try alternative device access
                if not device_name and hasattr(cast, '_device') and cast._device:
                    try:
                        device_name = getattr(cast._device, 'friendly_name', None)
                        logger.debug(f"Got device name from cast._device: {device_name}")
                    except:
                        pass
                
                # Method 3: Use service map from mDNS discovery
                if not device_name and host in service_map:
                    device_name = service_map[host]
                    logger.debug(f"Got device name from service map: {device_name}")
                
                # Method 4: Try to extract from cast properties
                if not device_name:
                    for attr in ['name', 'device_name', 'friendly_name']:
                        if hasattr(cast, attr):
                            potential_name = getattr(cast, attr, None)
                            if potential_name and isinstance(potential_name, str):
                                device_name = potential_name
                                logger.debug(f"Got device name from cast.{attr}: {device_name}")
                                break
                
                # Fallback to host-based name
                if not device_name:
                    device_name = f"Chromecast-{host}"
                    logger.debug(f"Using fallback name: {device_name}")
                
                device_info = {
                    "name": device_name,
                    "type": device_type,
                    "host": host,
                    "port": port,
                    "uuid": uuid,
                    "manufacturer": manufacturer,
                    "model": model
                }
                discovered_devices.append(device_info)
                logger.info(f"Found Chromecast: {device_info['name']} at {device_info['host']}")
                
            except Exception as e:
                logger.warning(f"Error getting info for Chromecast: {e}")
                # Final fallback - just add basic info
                try:
                    host = getattr(cast.socket_client, 'host', 'Unknown') if hasattr(cast, 'socket_client') else 'Unknown'
                    port = getattr(cast.socket_client, 'port', 8009) if hasattr(cast, 'socket_client') else 8009
                    
                    name = service_map.get(host, f"Device-{host}")
                    
                    discovered_devices.append({
                        "name": name,
                        "type": "Chromecast",
                        "host": host,
                        "port": port,
                        "uuid": None,
                        "manufacturer": "Google",
                        "model": "Unknown"
                    })
                    logger.info(f"Added device with fallback info: {name} at {host}")
                except Exception as e2:
                    logger.error(f"Could not get any info for device: {e2}")
        
        # Stop discovery to clean up
        pychromecast.discovery.stop_discovery(browser)
        
        logger.info(f"Discovery completed. Found {len(discovered_devices)} device(s)")
        return jsonify({"success": True, "chromecasts": discovered_devices})
        
    except ImportError:
        logger.error("pychromecast not available for device discovery")
        return jsonify({"success": False, "error": "pychromecast not installed"}), 500
    except Exception as e:
        logger.error(f"Error discovering Chromecasts: {e}")
        return jsonify({"success": False, "error": str(e)}), 500

@screen_cast_bp.route('/api/screen_cast/settings', methods=['GET', 'POST'])
@login_required
def screen_cast_settings():
    """Get or update screen cast settings"""
    try:
        if request.method == 'GET':
            # Return current settings
            settings = {
                "enabled": True,
                "stream_port": 8000,
                "chromecast_name": "Living Room",
                "resolution": "1280x720",
                "framerate": 15,
                "auto_start_capture": False,
                "auto_start_streaming": False
            }
            return jsonify({"success": True, "settings": settings})
        
        else:  # POST
            data = request.get_json()
            if not data:
                return jsonify({"success": False, "error": "No data provided"}), 400
            
            # Update settings through config manager
            logger.info(f"Updating screen cast settings: {data}")
            
            return jsonify({"success": True, "message": "Settings updated successfully"})
            
    except Exception as e:
        logger.error(f"Error handling screen cast settings: {e}")
        return jsonify({"success": False, "error": str(e)}), 500