"""
RTSP Streamer component for headless video playback and overlay streaming
"""

import sys
import time
import logging
import threading
import subprocess
import json
import http.server
import socketserver
import os
import shutil
import tempfile
from pathlib import Path
from typing import Optional, Dict, Any, List
from urllib.parse import urlparse

try:
    import ffmpeg
    FFMPEG_PYTHON_AVAILABLE = True
except ImportError:
    FFMPEG_PYTHON_AVAILABLE = False
    logging.warning("ffmpeg-python not available, falling back to subprocess")

from .thread_manager import ThreadedComponent
from .message_bus import MessageBus, Message, MessageType, MessageBuilder

logger = logging.getLogger(__name__)


class RTSPStreamer(ThreadedComponent):
    """HLS streamer that implements qt-player functionality in headless mode"""

    def __init__(self, message_bus: MessageBus, settings, debug_player: bool = False, test_mode: bool = False):
        super().__init__(name="headless_player", message_bus=message_bus)
        self.settings = settings
        self.debug_player = debug_player
        self.test_mode = test_mode

        # RTSP streaming settings (kept for compatibility)
        self.rtsp_port = 8554
        self.stream_name = "mbetterc_stream"
        self.rtsp_url = f"rtsp://127.0.0.1:{self.rtsp_port}/{self.stream_name}"

        # HTTP streaming settings (configurable)
        self.http_port = getattr(settings, 'streamer_port', 5884)  # Default to 5884
        self.http_url = f"http://127.0.0.1:{self.http_port}/{self.stream_name}.m3u8"

        # Video processing
        self.current_video_path = None
        self.ffmpeg_hls_process = None
        self.is_streaming = False

        # Continuous streaming components
        self.black_screen_file = None
        self.continuous_mode = True

        # Seamless switching using FIFO pipe
        self.fifo_pipe = None
        self.fifo_path = None
        self.current_input_process = None

        # Overlay data (simulated for headless mode)
        self.overlay_data = {
            'title': 'MbetterClient Headless Stream',
            'subtitle': 'RTSP Streaming Active',
            'ticker': 'Headless mode - no GUI display'
        }

        # Match tracking (similar to Qt player)
        self.is_playing_match_video = False
        self.current_match_id = None
        self.current_match_video_filename = None
        self.current_fixture_id = None

        # Video playback state management
        self.current_video_type = 'black_screen'  # 'black_screen', 'intro', 'match', 'result'
        self.video_loop_enabled = True  # Videos loop by default
        self.pending_video_request = None  # Store pending video requests
        self.video_end_timer = None  # Timer for video completion

        # HTTP server for HLS streaming
        self.http_server = None
        self.hls_dir = None

        logger.info("RTSPStreamer initialized")

    def initialize(self) -> bool:
        """Initialize the RTSP streamer"""
        try:
            logger.info("Initializing RTSP streamer...")

            # Register with message bus
            self.message_bus.register_component(self.name)

            # Check if ffmpeg is available
            if not self._check_ffmpeg():
                logger.error("FFmpeg not found - required for RTSP streaming")
                return False

            # Subscribe to messages
            self.message_bus.subscribe(self.name, MessageType.VIDEO_PLAY, self._handle_video_play)
            self.message_bus.subscribe(self.name, MessageType.VIDEO_PAUSE, self._handle_video_pause)
            self.message_bus.subscribe(self.name, MessageType.VIDEO_STOP, self._handle_video_stop)
            self.message_bus.subscribe(self.name, MessageType.VIDEO_SEEK, self._handle_video_seek)
            self.message_bus.subscribe(self.name, MessageType.VIDEO_VOLUME, self._handle_video_volume)
            self.message_bus.subscribe(self.name, MessageType.TEMPLATE_CHANGE, self._handle_template_change)
            self.message_bus.subscribe(self.name, MessageType.OVERLAY_UPDATE, self._handle_overlay_update)
            self.message_bus.subscribe(self.name, MessageType.START_INTRO, self._handle_start_intro)
            self.message_bus.subscribe(self.name, MessageType.PLAY_VIDEO_MATCH, self._handle_play_video_match)
            self.message_bus.subscribe(self.name, MessageType.PLAY_VIDEO_RESULT, self._handle_play_video_result)
            self.message_bus.subscribe(self.name, MessageType.GAME_STATUS, self._handle_game_status)

            # Start continuous streaming immediately
            logger.info("Starting continuous HLS streaming...")
            if not self._start_continuous_streaming():
                logger.error("Failed to start continuous streaming")
                return False

            logger.info(f"HLS streamer initialized - continuous streaming at {self.http_url}")
            return True

        except Exception as e:
            logger.error(f"RTSP streamer initialization failed: {e}")
            return False

    def run(self):
        """Main run loop for RTSP streamer"""
        logger.info("RTSP streamer main loop started")

        # In continuous mode, streaming is already started in initialize()
        # with black screen as default
        logger.info("Continuous streaming is active with black screen as default")

        # If test mode is enabled, automatically start intro video after a short delay
        if self.test_mode:
            logger.info("Test mode enabled - will automatically start intro video")
            threading.Timer(3.0, self._start_test_intro).start()

        last_heartbeat = time.time()

        while self.running:
            try:
                # Process messages
                message = self.message_bus.get_message(self.name, timeout=1.0)
                if message:
                    self._process_message(message)

                # Check streaming status
                if self.is_streaming:
                    hls_terminated = self.ffmpeg_hls_process and self.ffmpeg_hls_process.poll() is not None
                    input_terminated = self.current_input_process and self.current_input_process.poll() is not None

                    if hls_terminated or input_terminated:
                        logger.warning("FFmpeg streaming process terminated unexpectedly")
                        if hls_terminated:
                            logger.warning("HLS streaming process terminated")
                        if input_terminated:
                            logger.warning("Video input process terminated")
                            # If a non-black-screen video ended, switch back to black screen
                            if self.current_video_type != 'black_screen':
                                logger.info(f"Non-looping video ({self.current_video_type}) ended, switching to black screen")
                                self._switch_to_black_screen()
                            else:
                                self.is_streaming = False
                        else:
                            self.is_streaming = False

                # Send heartbeat every 10 seconds
                current_time = time.time()
                if current_time - last_heartbeat >= 10.0:
                    self.heartbeat()
                    last_heartbeat = current_time

                time.sleep(0.1)

            except Exception as e:
                logger.error(f"RTSP streamer error: {e}")
                time.sleep(1)

        logger.info("RTSP streamer main loop ended")

    def shutdown(self):
        """Shutdown the RTSP streamer"""
        logger.info("Shutting down RTSP streamer...")

        # Stop continuous streaming
        self._stop_continuous_streaming()

        # Stop HTTP server
        self._stop_http_server()

        super().shutdown()

    def _check_ffmpeg(self) -> bool:
        """Check if ffmpeg is available"""
        try:
            result = subprocess.run(['ffmpeg', '-version'],
                                  capture_output=True, text=True, timeout=5)
            if result.returncode == 0:
                logger.info("FFmpeg found and available")
                return True
            else:
                logger.error("FFmpeg not working properly")
                return False
        except (subprocess.TimeoutExpired, FileNotFoundError, subprocess.SubprocessError):
            logger.error("FFmpeg not found in PATH")
            logger.debug("To install FFmpeg on Ubuntu/Debian, run: sudo apt update && sudo apt install ffmpeg")
            return False

    def _start_continuous_streaming(self) -> bool:
        """Start continuous HLS streaming with black screen fallback"""
        try:
            logger.info("Starting continuous HLS streaming with black screen fallback...")

            # Create black screen video file
            if not self._create_black_screen_file():
                logger.error("Failed to create black screen file")
                return False

            # Create FIFO pipe for seamless switching
            if not self._create_fifo_pipe():
                logger.error("Failed to create FIFO pipe")
                return False

            # Start with black screen input process first
            if not self._start_video_input(self.black_screen_file, loop=True):
                logger.error("Failed to start initial black screen input")
                return False

            # Now start FFmpeg reading from FIFO pipe
            if not self._start_ffmpeg_hls_stream():
                logger.error("Failed to start FFmpeg HLS stream")
                return False

            # Mark as streaming successfully
            self.is_streaming = True
            logger.info("Continuous HLS streaming started successfully")
            return True

        except Exception as e:
            logger.error(f"Failed to start continuous HLS streaming: {e}")
            return False

    def _create_fifo_pipe(self) -> bool:
        """Create named FIFO pipe for seamless video switching"""
        try:
            import tempfile
            import os

            # Create FIFO pipe in temp directory
            temp_dir = tempfile.gettempdir()
            self.fifo_path = os.path.join(temp_dir, f"mbetterc_fifo_{os.getpid()}")

            # Remove existing FIFO if it exists
            if os.path.exists(self.fifo_path):
                os.unlink(self.fifo_path)

            # Create FIFO pipe
            os.mkfifo(self.fifo_path)
            logger.info(f"Created FIFO pipe: {self.fifo_path}")

            return True

        except Exception as e:
            logger.error(f"Failed to create FIFO pipe: {e}")
            return False

    def _start_ffmpeg_hls_stream(self) -> bool:
        """Start FFmpeg HLS streaming that reads from FIFO pipe continuously"""
        try:
            logger.info("Starting FFmpeg HLS streaming from FIFO pipe...")

            # Create HLS output directory
            self.hls_dir = tempfile.mkdtemp(prefix="mbetterc_hls_")
            hls_playlist = os.path.join(self.hls_dir, f"{self.stream_name}.m3u8")
            hls_segment_pattern = os.path.join(self.hls_dir, f"{self.stream_name}_%04d.ts")

            # FFmpeg command optimized for HLS streaming and VLC compatibility
            cmd = [
                'ffmpeg',
                '-y',  # Overwrite output files
                '-f', 'mpegts',  # Input format (MPEG-TS from FIFO)
                '-i', self.fifo_path,  # Read from FIFO pipe
                '-c:v', 'libx264',  # Video codec
                '-preset', 'veryfast',  # Encoding preset
                '-tune', 'zerolatency',  # Tune for low latency
                '-g', '48',  # GOP size (2 seconds at 24fps, aligned with 4-second segments)
                '-keyint_min', '48',  # Minimum keyframe interval
                '-sc_threshold', '0',  # Disable scene change detection for consistent GOPs
                '-c:a', 'aac',  # Audio codec
                '-b:a', '128k',  # Audio bitrate
                '-ac', '2',  # Stereo audio
                '-ar', '44100',  # Audio sample rate
                '-f', 'hls',  # Output format (HLS)
                '-hls_time', '4',  # Segment duration (4 seconds - better for VLC)
                '-hls_list_size', '15',  # Keep 15 segments in playlist (increased for smoother transitions)
                '-hls_flags', 'independent_segments+delete_segments',  # Better HLS compatibility
                '-hls_segment_filename', hls_segment_pattern,  # Segment filename pattern
                '-start_number', '0',  # Start segment numbering from 0
                '-hls_allow_cache', '0',  # Disable caching to ensure fresh segments
                hls_playlist  # HLS playlist file
            ]

            logger.info(f"Starting FFmpeg HLS streaming with command: {' '.join(cmd)}")

            self.ffmpeg_hls_process = subprocess.Popen(
                cmd,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True
            )
            logger.info(f"FFmpeg HLS subprocess created, PID: {self.ffmpeg_hls_process.pid}")

            # Start HTTP server
            self._start_http_server()

            # Wait for HLS playlist to be created (input process should already be running)
            time.sleep(3)

            # Check if HLS process is still running
            hls_process_running = self.ffmpeg_hls_process.poll() is None

            if hls_process_running:
                logger.info(f"HLS streaming started - playlist at {self.http_url}")
                return True
            else:
                logger.error("FFmpeg HLS process failed to start")
                self._stop_continuous_streaming()
                return False

        except Exception as e:
            logger.error(f"Failed to start FFmpeg HLS stream: {e}")
            return False

    def _switch_to_video(self, video_path: str):
        """Switch streaming to video file by changing FIFO input"""
        try:
            logger.info(f"Switching streaming to video: {video_path}")

            # Stop current input process
            if self.current_input_process:
                logger.info("Stopping current input process...")
                self.current_input_process.terminate()
                try:
                    self.current_input_process.wait(timeout=2)
                except subprocess.TimeoutExpired:
                    logger.warning("Input process didn't terminate gracefully, killing...")
                    self.current_input_process.kill()
                    self.current_input_process.wait()
                self.current_input_process = None

            # Brief pause to ensure clean transition
            time.sleep(0.5)

            # Set new video path
            self.current_video_path = video_path

            # Start new input process feeding into FIFO
            success = self._start_video_input(video_path, loop=False)

            if success:
                # Always restart HLS process for clean segment generation during video switches
                logger.info("Restarting HLS process for clean video transition...")
                if self.ffmpeg_hls_process:
                    logger.info("Stopping current HLS process...")
                    self.ffmpeg_hls_process.terminate()
                    try:
                        self.ffmpeg_hls_process.wait(timeout=2)
                    except subprocess.TimeoutExpired:
                        logger.warning("HLS process didn't terminate gracefully, killing...")
                        self.ffmpeg_hls_process.kill()
                        self.ffmpeg_hls_process.wait()
                    self.ffmpeg_hls_process = None

                # Clean up old HLS directory
                if self.hls_dir and os.path.exists(self.hls_dir):
                    import shutil
                    shutil.rmtree(self.hls_dir)
                    self.hls_dir = None

                # Restart HLS streaming with fresh directory
                if not self._start_ffmpeg_hls_stream():
                    logger.error("Failed to restart HLS streaming after video switch")
                    return False

                logger.info("Video switch completed successfully - HLS process restarted")
                return True
            else:
                logger.error("Failed to start new video input process")
                return False

        except Exception as e:
            logger.error(f"Failed to switch to video: {e}")
            return False

    def _start_video_input(self, video_path: str, loop: bool = False) -> bool:
        """Start FFmpeg process to feed video into FIFO pipe"""
        try:
            logger.info(f"Starting video input process for: {video_path} (loop={loop})")

            # FFmpeg command to read video and output to FIFO pipe
            cmd = [
                'ffmpeg',
                '-re',  # Read input at native frame rate
                '-i', video_path,  # Input video file
                '-c', 'copy',  # Copy streams without re-encoding (faster)
                '-f', 'mpegts',  # Output format (MPEG-TS for FIFO)
                '-y',  # Overwrite output
                self.fifo_path  # Output to FIFO pipe
            ]

            # Add loop option only for black screen
            if loop:
                cmd.insert(2, '-stream_loop')
                cmd.insert(3, '-1')

            logger.info(f"Starting video input with command: {' '.join(cmd)}")

            self.current_input_process = subprocess.Popen(
                cmd,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True
            )

            logger.info(f"Video input process started, PID: {self.current_input_process.pid}")

            # Wait a moment for the process to start
            time.sleep(1)

            # Check if process is still running
            if self.current_input_process.poll() is None:
                logger.info("Video input process is running successfully")
                return True
            else:
                logger.error("Video input process failed to start")
                return False

        except Exception as e:
            logger.error(f"Failed to start video input: {e}")
            return False

    def _switch_to_black_screen(self):
        """Switch streaming to black screen by changing FIFO input"""
        try:
            logger.info("Switching streaming to black screen")

            # Stop current input process
            if self.current_input_process:
                logger.info("Stopping current input process...")
                self.current_input_process.terminate()
                try:
                    self.current_input_process.wait(timeout=2)
                except subprocess.TimeoutExpired:
                    logger.warning("Input process didn't terminate gracefully, killing...")
                    self.current_input_process.kill()
                    self.current_input_process.wait()
                self.current_input_process = None

            # Brief pause to ensure clean transition
            time.sleep(0.5)

            # Set black screen as current video
            self.current_video_path = self.black_screen_file
            self.current_video_type = 'black_screen'

            # Start black screen input
            success = self._start_video_input(self.black_screen_file, loop=True)

            if success:
                # Always restart HLS process for clean segment generation during switches
                logger.info("Restarting HLS process for clean black screen transition...")
                if self.ffmpeg_hls_process:
                    logger.info("Stopping current HLS process...")
                    self.ffmpeg_hls_process.terminate()
                    try:
                        self.ffmpeg_hls_process.wait(timeout=2)
                    except subprocess.TimeoutExpired:
                        logger.warning("HLS process didn't terminate gracefully, killing...")
                        self.ffmpeg_hls_process.kill()
                        self.ffmpeg_hls_process.wait()
                    self.ffmpeg_hls_process = None

                # Clean up old HLS directory
                if self.hls_dir and os.path.exists(self.hls_dir):
                    import shutil
                    shutil.rmtree(self.hls_dir)
                    self.hls_dir = None

                # Restart HLS streaming with fresh directory
                if not self._start_ffmpeg_hls_stream():
                    logger.error("Failed to restart HLS streaming after black screen switch")
                    return False

                logger.info("Black screen switch completed successfully - HLS process restarted")
                return True
            else:
                logger.error("Failed to start black screen input process")
                return False

        except Exception as e:
            logger.error(f"Failed to switch to black screen: {e}")
            return False

    def _create_black_screen_file(self) -> bool:
        """Create a looping black screen video file"""
        try:
            # Create black screen video file in temp directory
            temp_dir = tempfile.gettempdir()
            self.black_screen_file = os.path.join(temp_dir, f"mbetterc_black_{os.getpid()}.mp4")

            # Remove existing file if it exists
            if os.path.exists(self.black_screen_file):
                os.unlink(self.black_screen_file)

            # Create a 10-second looping black screen video
            cmd = [
                'ffmpeg',
                '-f', 'lavfi',  # Use libavfilter input
                '-i', 'color=c=black:s=1920x1080:r=30:d=10',  # Black color, 10 seconds
                '-f', 'lavfi',  # Audio input
                '-i', 'anullsrc=r=44100:cl=stereo',  # Silent audio
                '-c:v', 'libx264',  # Video codec
                '-preset', 'ultrafast',  # Fast encoding
                '-c:a', 'aac',  # Audio codec
                '-shortest',  # End when shortest input ends
                '-y',  # Overwrite output
                self.black_screen_file  # Output file
            ]

            logger.info("Creating black screen video file...")
            result = subprocess.run(
                cmd,
                capture_output=True,
                text=True,
                timeout=30
            )

            if result.returncode == 0 and os.path.exists(self.black_screen_file):
                logger.info(f"Created black screen video file: {self.black_screen_file}")
                return True
            else:
                logger.error(f"Failed to create black screen file: {result.stderr}")
                return False

        except Exception as e:
            logger.error(f"Failed to create black screen file: {e}")
            return False


    def _stop_continuous_streaming(self):
        """Stop continuous HLS streaming"""
        try:
            logger.info("Stopping continuous streaming...")

            # Stop input process first
            if self.current_input_process:
                logger.info("Stopping video input process...")
                self.current_input_process.terminate()
                try:
                    self.current_input_process.wait(timeout=2)
                except subprocess.TimeoutExpired:
                    logger.warning("Input process didn't terminate gracefully, killing...")
                    self.current_input_process.kill()
                    self.current_input_process.wait()
                self.current_input_process = None

            # Stop HLS process
            if self.ffmpeg_hls_process:
                logger.info("Stopping HLS streaming...")
                self.ffmpeg_hls_process.terminate()
                try:
                    self.ffmpeg_hls_process.wait(timeout=5)
                except subprocess.TimeoutExpired:
                    logger.warning("FFmpeg HLS process didn't terminate gracefully, killing...")
                    self.ffmpeg_hls_process.kill()
                    self.ffmpeg_hls_process.wait()
                self.ffmpeg_hls_process = None

            # Clean up FIFO pipe
            if self.fifo_path and os.path.exists(self.fifo_path):
                try:
                    os.unlink(self.fifo_path)
                    logger.info(f"Removed FIFO pipe: {self.fifo_path}")
                except Exception as e:
                    logger.warning(f"Failed to remove FIFO pipe: {e}")
                self.fifo_path = None

            # Clean up black screen file
            if self.black_screen_file and os.path.exists(self.black_screen_file):
                try:
                    os.unlink(self.black_screen_file)
                    logger.info(f"Removed black screen file: {self.black_screen_file}")
                except Exception as e:
                    logger.warning(f"Failed to remove black screen file: {e}")
                self.black_screen_file = None

            self.is_streaming = False
            self.current_video_path = None

            # Clean up HLS directory
            if self.hls_dir and os.path.exists(self.hls_dir):
                shutil.rmtree(self.hls_dir)
                self.hls_dir = None

            logger.info("Continuous streaming stopped")

        except Exception as e:
            logger.error(f"Error stopping continuous streaming: {e}")


    def _start_http_server(self):
        """Start HTTP server to serve HLS files"""
        try:
            if self.http_server:
                logger.warning("HTTP server already running")
                return

            # Create a custom request handler that serves files from the HLS directory
            class HLSRequestHandler(http.server.SimpleHTTPRequestHandler):
                def __init__(self, *args, streamer=None, **kwargs):
                    self.streamer = streamer
                    super().__init__(*args, **kwargs)

                def translate_path(self, path):
                    # Serve files from the current HLS directory
                    if self.streamer and self.streamer.hls_dir:
                        # Remove leading slash and join with HLS directory
                        path = path.lstrip('/')
                        file_path = os.path.join(self.streamer.hls_dir, path)
                        if os.path.exists(file_path) and os.path.isfile(file_path):
                            return file_path
                        else:
                            # File doesn't exist, return a non-existent path to trigger 404
                            return "/nonexistent_file_404"
                    else:
                        # No active stream, return 404
                        return "/nonexistent_file_404"

                def do_GET(self):
                    try:
                        # Check if we have an active stream
                        if not self.streamer or not self.streamer.hls_dir:
                            self.send_error(404, "No active stream. Start streaming first.")
                            return

                        # Check if the requested file exists
                        file_path = self.translate_path(self.path)
                        if not os.path.exists(file_path):
                            self.send_error(404, "File not found")
                            return

                        # Serve the file
                        super().do_GET()
                    except (ConnectionResetError, BrokenPipeError, OSError) as e:
                        # Handle connection errors gracefully during video transitions
                        logger.debug(f"Connection error during HLS request: {e}")
                        # Don't send error response as connection is already broken
                        return
                    except Exception as e:
                        logger.warning(f"Unexpected error in HLS request handler: {e}")
                        try:
                            self.send_error(500, "Internal server error")
                        except (ConnectionResetError, BrokenPipeError, OSError):
                            # Connection already broken, can't send error
                            pass

                def log_message(self, format, *args):
                    # Suppress HTTP server logs
                    pass

            # Create HTTP server
            self.http_server = socketserver.TCPServer(("", self.http_port), lambda *args, **kwargs: HLSRequestHandler(*args, streamer=self, **kwargs))
            logger.info(f"HTTP server created on port {self.http_port}")

            # Run server in a separate thread
            server_thread = threading.Thread(target=self.http_server.serve_forever, daemon=True)
            server_thread.start()
            logger.info(f"HTTP server started on port {self.http_port}")

        except Exception as e:
            logger.error(f"Failed to start HTTP server: {e}")

    def _stop_http_server(self):
        """Stop HTTP server"""
        try:
            if self.http_server:
                logger.info("Stopping HTTP server...")
                self.http_server.shutdown()
                self.http_server.server_close()
                self.http_server = None
                logger.info("HTTP server stopped")
        except Exception as e:
            logger.error(f"Error stopping HTTP server: {e}")

    def _update_overlay(self, data: Dict[str, Any]):
        """Update overlay data for headless mode"""
        try:
            self.overlay_data.update(data)
            logger.debug(f"Overlay updated: {self.overlay_data}")

            # In headless mode, we could potentially overlay text on the video stream
            # using ffmpeg filters, but for now we'll just log the overlay data

        except Exception as e:
            logger.error(f"Failed to update overlay: {e}")

    def _process_message(self, message: Message):
        """Process incoming messages"""
        try:
            if self.debug_player:
                logger.info(f"RTSPStreamer processing message: {message.type.value}")

            # Route to appropriate handlers
            if message.type == MessageType.VIDEO_PLAY:
                self._handle_video_play(message)
            elif message.type == MessageType.VIDEO_PAUSE:
                self._handle_video_pause(message)
            elif message.type == MessageType.VIDEO_STOP:
                self._handle_video_stop(message)
            elif message.type == MessageType.VIDEO_SEEK:
                self._handle_video_seek(message)
            elif message.type == MessageType.VIDEO_VOLUME:
                self._handle_video_volume(message)
            elif message.type == MessageType.TEMPLATE_CHANGE:
                self._handle_template_change(message)
            elif message.type == MessageType.OVERLAY_UPDATE:
                self._handle_overlay_update(message)
            elif message.type == MessageType.START_INTRO:
                self._handle_start_intro(message)
            elif message.type == MessageType.PLAY_VIDEO_MATCH:
                self._handle_play_video_match(message)
            elif message.type == MessageType.PLAY_VIDEO_RESULT:
                self._handle_play_video_result(message)
            elif message.type == MessageType.GAME_STATUS:
                self._handle_game_status(message)
            else:
                logger.debug(f"Unhandled message type in RTSPStreamer: {message.type}")

        except Exception as e:
            logger.error(f"Failed to process message: {e}")

    # Message handlers (similar to Qt player but for RTSP streaming)

    def _handle_video_play(self, message: Message):
        """Handle video play message"""
        try:
            file_path = message.data.get("file_path")
            template_data = message.data.get("overlay_data", {})
            template_name = message.data.get("template")

            if not file_path:
                logger.error("No file path provided for video play")
                return

            logger.info(f"RTSPStreamer: Switching to video {file_path}")

            # Update overlay data
            if template_data:
                self._update_overlay(template_data)

            # Switch to video streaming
            self._switch_to_video(file_path)

        except Exception as e:
            logger.error(f"Failed to handle video play: {e}")

    def _handle_video_pause(self, message: Message):
        """Handle video pause message"""
        # For continuous streaming, pause means switch to black screen
        logger.info("RTSPStreamer: Pausing (switching to black screen)")
        self._switch_to_black_screen()

    def _handle_video_stop(self, message: Message):
        """Handle video stop message"""
        logger.info("RTSPStreamer: Stopping video (switching to black screen)")
        self._switch_to_black_screen()

    def _handle_video_seek(self, message: Message):
        """Handle video seek message"""
        # RTSP streaming doesn't support seeking in the same way
        # Would need to restart stream at different position
        position = message.data.get("position", 0)
        logger.info(f"RTSPStreamer: Seek to position {position} (not implemented for RTSP)")

    def _handle_video_volume(self, message: Message):
        """Handle video volume message"""
        # Volume control in RTSP stream would require restarting ffmpeg with different audio settings
        volume = message.data.get("volume", 100)
        logger.info(f"RTSPStreamer: Volume change to {volume}% (not implemented for RTSP)")

    def _handle_template_change(self, message: Message):
        """Handle template change message"""
        template_name = message.data.get("template_name", "")
        template_data = message.data.get("template_data", {})

        logger.info(f"RTSPStreamer: Template change to {template_name}")

        # Update overlay data
        if template_data:
            self._update_overlay(template_data)

    def _handle_overlay_update(self, message: Message):
        """Handle overlay update message"""
        overlay_data = message.data.get("overlay_data", {})
        self._update_overlay(overlay_data)

    def _handle_start_intro(self, message: Message):
        """Handle START_INTRO message"""
        logger.info("RTSPStreamer: Handling START_INTRO message")

        # Similar logic to Qt player but for RTSP streaming
        match_id = message.data.get("match_id")
        fixture_id = message.data.get("fixture_id")

        # Find intro video
        intro_path = self._find_intro_video_file(match_id)

        if intro_path:
            logger.info(f"RTSPStreamer: Starting intro video: {intro_path}")

            # Set up loop control for intro video
            loop_data = {
                'infinite_loop': True,
                'continuous_playback': True
            }

            # Play intro video with RTSP streaming
            overlay_data = {
                "title": "Intro Video",
                "subtitle": "Preparing for match...",
                "match_id": match_id,
                "fixture_id": fixture_id
            }

            self._update_overlay(overlay_data)
            self._switch_to_video(str(intro_path))
            self.current_video_type = 'intro'

        else:
            logger.warning("RTSPStreamer: No intro video found")

    def _handle_play_video_match(self, message: Message):
        """Handle PLAY_VIDEO_MATCH message"""
        try:
            logger.info("RTSPStreamer: Handling PLAY_VIDEO_MATCH message")

            match_id = message.data.get("match_id")
            video_filename = message.data.get("video_filename")
            fixture_id = message.data.get("fixture_id")
            result = message.data.get("result")

            if not match_id or not video_filename:
                logger.error("RTSPStreamer: Missing match_id or video_filename")
                return

            # Switch to match video (continuous streaming)
            match_video_path = self._find_match_video_file(match_id, video_filename)

            if match_video_path:
                logger.info(f"RTSPStreamer: Switching to match video: {match_video_path}")

                # Set match tracking
                self.is_playing_match_video = True
                self.current_match_id = match_id
                self.current_match_video_filename = video_filename
                self.current_fixture_id = fixture_id

                # Update overlay
                overlay_data = {
                    "title": f"Match {match_id}",
                    "subtitle": f"Result: {result}" if result else "Live Action",
                    "result": result,
                    "match_id": match_id,
                    "fixture_id": fixture_id
                }

                self._update_overlay(overlay_data)
                self._switch_to_video(str(match_video_path))
                self.current_video_type = 'match'

            else:
                logger.error(f"RTSPStreamer: Match video not found: {video_filename}")

        except Exception as e:
            logger.error(f"RTSPStreamer: Failed to handle PLAY_VIDEO_MATCH: {e}")

    def _handle_play_video_result(self, message: Message):
        """Handle PLAY_VIDEO_RESULTS message"""
        try:
            logger.info("RTSPStreamer: Handling PLAY_VIDEO_RESULTS message")

            fixture_id = message.data.get("fixture_id")
            match_id = message.data.get("match_id")
            result = message.data.get("result")
            winning_outcomes = message.data.get("winning_outcomes", [])

            # Find result video
            result_video_path = self._find_result_video_file(match_id, result)

            if result_video_path:
                logger.info(f"RTSPStreamer: Switching to result video: {result_video_path}")

                # Update match tracking
                if self.is_playing_match_video:
                    self.is_playing_match_video = False

                # Update overlay with results
                overlay_data = {
                    'outcome': result,
                    'result': result,
                    'winningOutcomes': [{'outcome': outcome} for outcome in winning_outcomes],
                    'match_id': match_id,
                    'fixture_id': fixture_id,
                    'is_result_video': True
                }

                self._update_overlay(overlay_data)
                self._switch_to_video(str(result_video_path))
                self.current_video_type = 'result'

            else:
                logger.error(f"RTSPStreamer: Result video not found for {result}")

        except Exception as e:
            logger.error(f"RTSPStreamer: Failed to handle PLAY_VIDEO_RESULTS: {e}")

    def _handle_game_status(self, message: Message):
        """Handle GAME_STATUS messages"""
        status = message.data.get("status")
        logger.info(f"RTSPStreamer: Game status: {status}")

        # Similar logic to Qt player for determining when to play intro

    def _start_test_intro(self):
        """Automatically start intro video for testing in headless mode"""
        try:
            logger.info("RTSPStreamer: Starting test intro video")

            # Create a START_INTRO message and handle it
            intro_message = Message(
                type=MessageType.START_INTRO,
                sender="test_mode",
                data={
                    "match_id": None,
                    "fixture_id": None
                }
            )

            self._handle_start_intro(intro_message)
            logger.info("RTSPStreamer: Test intro video started successfully")

        except Exception as e:
            logger.error(f"RTSPStreamer: Failed to start test intro: {e}")

    # Helper methods (similar to Qt player)

    def _find_intro_video_file(self, match_id: int) -> Optional[Path]:
        """Find intro video file"""
        try:
            # Go up to project root: mbetterclient/core/rtsp_streamer.py -> mbetterclient/core -> mbetterclient -> project_root
            assets_dir = Path(__file__).parent.parent.parent / "assets"
            intro_file = assets_dir / "INTRO.mp4"

            if intro_file.exists():
                logger.info(f"RTSPStreamer: Found intro video: {intro_file}")
                return intro_file
            else:
                logger.warning(f"RTSPStreamer: Intro video not found: {intro_file}")
                return None

        except Exception as e:
            logger.error(f"RTSPStreamer: Failed to find intro video: {e}")
            return None

    def _find_match_video_file(self, match_id: int, video_filename: str) -> Optional[Path]:
        """Find match video file from extracted ZIP"""
        try:
            import tempfile
            temp_base = Path(tempfile.gettempdir())
            temp_dir_pattern = f"match_{match_id}_"

            for temp_dir in temp_base.glob(f"{temp_dir_pattern}*"):
                if temp_dir.is_dir():
                    video_file = temp_dir / video_filename
                    if video_file.exists():
                        logger.info(f"RTSPStreamer: Found match video: {video_file}")
                        return video_file

            logger.warning(f"RTSPStreamer: Match video not found: {video_filename}")
            return None

        except Exception as e:
            logger.error(f"RTSPStreamer: Failed to find match video: {e}")
            return None

    def _find_result_video_file(self, match_id: int, result: str) -> Optional[Path]:
        """Find result video file"""
        try:
            import tempfile
            temp_base = Path(tempfile.gettempdir())
            temp_dir_pattern = f"match_{match_id}_"

            result_filename = f"{result}.mp4"

            for temp_dir in temp_base.glob(f"{temp_dir_pattern}*"):
                if temp_dir.is_dir():
                    result_file = temp_dir / result_filename
                    if result_file.exists():
                        logger.info(f"RTSPStreamer: Found result video: {result_file}")
                        return result_file

            logger.warning(f"RTSPStreamer: Result video not found: {result_filename}")
            return None

        except Exception as e:
            logger.error(f"RTSPStreamer: Failed to find result video: {e}")
            return None