import subprocess
import socket
import os
import socket
import sys
import time
import logging

from .constants import DEFAULT_LOG_DIR, BROWSER_EXECUTABLE, BROWSER_PROCESS_NAME

logger = logging.getLogger(__name__)

# 浏览器日志目录，可通过 set_browser_log_dir() 动态设置
_browser_log_dir = DEFAULT_LOG_DIR

def set_browser_log_dir(log_dir: str):
    """Set the directory for browser log file."""
    global _browser_log_dir
    _browser_log_dir = log_dir

def get_local_ip():
    return "127.0.0.1"

def run_shell(cmd, env=None, need_sudo=False):
    if sys.platform == "win32":
        # Windows 不支持 sudo
        actual_cmd = cmd
    else:
        actual_cmd = f"sudo bash -c {repr(cmd)}" if need_sudo else cmd
    logger.info(f"\n>>> 执行命令: {actual_cmd}")
    try:
        result = subprocess.run(
            actual_cmd, shell=True, capture_output=True, text=True, env=env
        )
        logger.info(result.stdout.rstrip())
        if result.stderr:
            logger.info(result.stderr.rstrip())
        if result.returncode != 0:
            logger.info(f"命令执行失败，返回码: {result.returncode}")
        return result.returncode
    except Exception as e:
        logger.info(f"命令执行异常: {e}")
        return -1
    
def run_shell_async(cmd, need_sudo=False):
    if sys.platform == "win32":
        # Windows 不支持 sudo
        async_cmd = cmd
    else:
        async_cmd = f"sudo bash -c {repr(cmd + ' &')}" if need_sudo else cmd
    logger.info(f"\n>>> 异步执行命令: {async_cmd}")
    try:
        proc = subprocess.Popen(
            async_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True,
            bufsize=1
        )
        import threading
        def print_output(p):
            for line in p.stdout:
                logger.info(line.rstrip())

        threading.Thread(target=print_output, args=(proc,), daemon=True).start()
        logger.info(f"异步命令执行成功 {async_cmd}")
        return proc
    except Exception as e:
        logger.info(f"异步命令执行异常: {e}")
        return None


def check_qqbrowser_alive():
    """
    检查qqbrowser进程是否存在，存在返回True，不存在返回False。
    仅用于 Linux 平台。
    """
    try:
        result = subprocess.run(['pgrep', '-x', 'qqbrowser'], capture_output=True, text=True)
        return result.returncode == 0
    except Exception:
        return False


def _check_qqbrowser_alive_mac():
    """
    检查 QQ 浏览器进程是否存在（macOS 平台）。
    """
    try:
        result = subprocess.run(
            ["pgrep", "-x", BROWSER_PROCESS_NAME],
            capture_output=True, text=True,
        )
        return result.returncode == 0
    except Exception:
        return False


def _check_qqbrowser_alive_win():
    """
    检查 QQ 浏览器进程是否存在（Windows 平台）。
    """
    try:
        result = subprocess.run(
            ["tasklist", "/FI", f"IMAGENAME eq {BROWSER_PROCESS_NAME}", "/NH"],
            capture_output=True, text=True,
        )
        return BROWSER_PROCESS_NAME.lower() in result.stdout.lower()
    except Exception:
        return False

def start_qqbrowser_fullscreen(url=None):
    """启动QQ浏览器全屏模式，仅用于 Linux 平台。"""
    try:
        # 设置默认URL
        url = "https://www.qq.com"
        logger.info(f"启动QQ浏览器，访问URL: {url}")

        log_file = os.path.join(_browser_log_dir, "qb_log.log")

        # 构建QQ浏览器启动命令（Linux）
        browser_cmd = (
            f"qqbrowser-browser-stable "
            f"--headless=new "
            f"--display-invisible-extension=true "
            f"--disable-infobars "
            f"--start-maximized "
            f"--x5use-automatic-in-tab "
            f"--no-first-run "
            f"--no-crashed-bubble-view "
            f"--disable-infobars "
            f"--no-modal-dialogs "
            f"--no-external-protocol-dialogs "
            f"--no-sandbox "
            f"about:blank >> {log_file} 2>&1"
        )

        logger.info(f"执行QQ浏览器启动命令: {browser_cmd}")
        proc = run_shell_async(browser_cmd, need_sudo=False)

        if proc is None:
            logger.info("QQ浏览器启动失败")
            return False

        # 等待一小段时间检查浏览器进程
        time.sleep(2)
        check_cmd = "pgrep -f qqbrowser"
        exit_code = run_shell(check_cmd)

        if exit_code == 0:
            logger.info("QQ浏览器已成功启动")
            return True
        else:
            logger.info("警告: QQ浏览器可能未成功启动")
            return False

    except Exception as e:
        logger.info(f"启动QQ浏览器时发生错误: {str(e)}")
        return False


def _start_qqbrowser_mac(url=None):
    """启动 QQ 浏览器全屏模式（macOS 平台）。"""
    try:
        url = "https://www.qq.com"
        logger.info(f"启动QQ浏览器（macOS），访问URL: {url}")

        log_file = os.path.join(_browser_log_dir, "qb_log.log")

        browser_cmd = (
            f'"{BROWSER_EXECUTABLE}" '
            f"--display-invisible-extension=true "
            f"--disable-infobars "
            f"--start-maximized "
            f"--x5use-automatic-in-tab "
            f"--no-first-run "
            f"--no-crashed-bubble-view "
            f"--no-modal-dialogs "
            f"--no-external-protocol-dialogs "
            f"about:blank >> {log_file} 2>&1"
        )

        logger.info(f"执行QQ浏览器启动命令: {browser_cmd}")
        proc = run_shell_async(browser_cmd, need_sudo=False)

        if proc is None:
            logger.info("QQ浏览器启动失败")
            return False

        time.sleep(2)
        if _check_qqbrowser_alive_mac():
            logger.info("QQ浏览器已成功启动")
            return True
        else:
            logger.info("警告: QQ浏览器可能未成功启动")
            return False

    except Exception as e:
        logger.info(f"启动QQ浏览器时发生错误: {str(e)}")
        return False


def _start_qqbrowser_win(url=None):
    """启动 QQ 浏览器全屏模式（Windows 平台）。"""
    try:
        url = "https://www.qq.com"
        logger.info(f"启动QQ浏览器（Windows），访问URL: {url}")

        log_file = os.path.join(_browser_log_dir, "qb_log.log")

        browser_cmd = (
            f'"{BROWSER_EXECUTABLE}" '
            f"--display-invisible-extension=true "
            f"--disable-infobars "
            f"--start-maximized "
            f"--x5use-automatic-in-tab "
            f"--no-first-run "
            f"--no-crashed-bubble-view "
            f"--no-modal-dialogs "
            f"--no-external-protocol-dialogs "
            f'about:blank >> "{log_file}" 2>&1'
        )

        logger.info(f"执行QQ浏览器启动命令: {browser_cmd}")
        proc = run_shell_async(browser_cmd, need_sudo=False)

        if proc is None:
            logger.info("QQ浏览器启动失败")
            return False

        time.sleep(2)
        if _check_qqbrowser_alive_win():
            logger.info("QQ浏览器已成功启动")
            return True
        else:
            logger.info("警告: QQ浏览器可能未成功启动")
            return False

    except Exception as e:
        logger.info(f"启动QQ浏览器时发生错误: {str(e)}")
        return False


def check_and_run_browser(url=None):
    """
    检查浏览器是否运行，未运行则启动。
    根据当前平台自动分发到对应的检测和启动方法。
    """
    if sys.platform == "win32":
        if not _check_qqbrowser_alive_win():
            logger.info("浏览器进程未启动（Windows），尝试启动")
            _start_qqbrowser_win(url)
    elif sys.platform == "darwin":
        if not _check_qqbrowser_alive_mac():
            logger.info("浏览器进程未启动（macOS），尝试启动")
            _start_qqbrowser_mac(url)
    else:
        # Linux 走原有逻辑
        if not check_qqbrowser_alive():
            logger.info("浏览器进程未启动，尝试启动")
            start_qqbrowser_fullscreen(url)
    return ""