import json
import re
import subprocess
import threading
import time
import urllib.parse

import xbmc
import xbmcaddon
import xbmcgui

from tools import debug_log


def launch_mpv_for_current_channel(window):
    """Launch mpv for the currently selected channel in EPGGrid."""

    def _launch_mpv_from_context():
        try:
            time.sleep(0.2)
            channel_idx = window.current_channel_idx
            if channel_idx >= len(window.channels):
                debug_log(
                    f"DEBUG: Invalid channel_idx={channel_idx}, channels_len={len(window.channels)}",
                    xbmc.LOGERROR,
                )
                xbmcgui.Dialog().notification('Error', 'Invalid channel selected', xbmcgui.NOTIFICATION_ERROR, 3000)
                return

            channel = window.channels[channel_idx]
            stream_url = _get_current_playing_stream_url()
            if not stream_url:
                stream_url = channel.get('url') or channel.get('stream_url')
            if not stream_url:
                xbmcgui.Dialog().notification('Error', 'No stream URL found for channel', xbmcgui.NOTIFICATION_ERROR, 3000)
                return

            resolved_url, resolved_headers = _get_resolved_url(stream_url)
            if not resolved_url.startswith("http"):
                xbmcgui.Dialog().notification('Error', 'Could not resolve direct stream URL', xbmcgui.NOTIFICATION_ERROR, 3000)
                return

            mpv_path = xbmcaddon.Addon().getSetting("mpv_path") or r"C:\Users\user\Desktop\mpv_player\mpv.exe"
            mpv_command = [mpv_path]
            if resolved_headers:
                mpv_headers = ",".join([f"{k.title()}: {v}" for k, v in resolved_headers.items()])
                mpv_command += [f'--http-header-fields={mpv_headers}']
            mpv_command.append(resolved_url)
            debug_log(f"DEBUG: Launching mpv with command: {mpv_command}", xbmc.LOGINFO)

            create_new_console = 0x00000010
            subprocess.Popen(mpv_command, creationflags=create_new_console)
            xbmcgui.Dialog().notification("mpv", "Stream sent to mpv player", xbmcgui.NOTIFICATION_INFO, 2000)
        except Exception as e:
            debug_log(f"DEBUG: Failed to launch mpv: {str(e)}", xbmc.LOGERROR)
            xbmcgui.Dialog().ok("Error", f"Failed to launch mpv: {str(e)}")

    threading.Thread(target=_launch_mpv_from_context, daemon=True).start()


def _get_resolved_url(url):
    resolved_headers = {}

    proxy_match = re.match(r"http://127\.0\.0\.1:\d+\?url=(http.*)", url)
    if proxy_match:
        url = urllib.parse.unquote(proxy_match.group(1))

    if url.startswith("plugin://"):
        # Avoid triggering plugin playback UI from context-menu mpv action.
        debug_log(f"DEBUG: Unresolved plugin URL for mpv launch: {url}", xbmc.LOGWARNING)

    if url and "|" in url:
        url_parts = url.split("|", 1)
        url = url_parts[0]
        try:
            header_string = url_parts[1]
            for header in header_string.split('&'):
                if '=' in header:
                    key, value = header.split('=', 1)
                    resolved_headers[key.lower()] = urllib.parse.unquote(value)
        except Exception as e:
            debug_log(f"DEBUG: Error parsing headers from URL: {str(e)}", xbmc.LOGWARNING)

    return url, resolved_headers


def _get_current_playing_stream_url():
    try:
        player = xbmc.Player()
        if not player.isPlaying():
            return None

        playing_file = player.getPlayingFile()
        if playing_file:
            return playing_file

        jsonrpc_request = {
            'jsonrpc': '2.0',
            'method': 'Player.GetItem',
            'params': {'playerid': 1},
            'id': 1,
        }
        result = xbmc.executeJSONRPC(json.dumps(jsonrpc_request))
        data = json.loads(result)
        return data.get('result', {}).get('item', {}).get('file', '')
    except Exception as e:
        debug_log(f"DEBUG: Failed reading current playing stream URL: {str(e)}", xbmc.LOGWARNING)
        return None
