"""
QQ Browser macOS installer.

从官方下载服务器下载 QQ Browser 的 macOS 安装包（.dmg），
挂载磁盘映像并将 .app 拷贝到 /Applications 目录。
"""

import glob
import logging
import os
import platform
import shutil
import subprocess
import sys
import tempfile
from pathlib import Path

logger = logging.getLogger(__name__)

from .installer_common import (
    _setup_install_logging,
    _teardown_install_logging,
    _log_and_print,
    _run,
    _download,
)
from .constants import BROWSER_EXECUTABLE

# ---------------------------------------------------------------------------
# Constants
# ---------------------------------------------------------------------------

BASE_URL = "https://dldir1v6.qq.com/invc/tt/QB/Public"
QB_DMG = "QQBrowser.dmg"
QB_APP_NAME = "QQBrowser.app"
QB_INSTALL_DIR = "/Applications"


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------

def _check_platform():
    """确保当前运行在 macOS 平台上。"""
    if sys.platform != "darwin":
        _log_and_print(f"❌ Unsupported platform: {sys.platform}. This installer is for macOS only.", logging.ERROR)
        sys.exit(1)


def is_installed() -> bool:
    """检查 QQ Browser 是否已安装。

    通过检查 /Applications 和可执行文件路径来判断。
    """
    # 方式 1：检查 .app bundle
    app_path = os.path.join(QB_INSTALL_DIR, QB_APP_NAME)
    if os.path.isdir(app_path):
        return True

    # 方式 2：检查可执行文件
    if os.path.isfile(BROWSER_EXECUTABLE):
        return True

    return False


# ---------------------------------------------------------------------------
# Install logic
# ---------------------------------------------------------------------------

def _install_dmg(tmp_dir: Path):
    """下载并安装 QQ Browser（macOS .dmg）。"""
    pkg_path = tmp_dir / QB_DMG
    url = f"{BASE_URL}/{QB_DMG}"

    _log_and_print(f"📦 Downloading macOS installer: {QB_DMG}")
    _download(url, pkg_path)

    _log_and_print("📦 Mounting disk image...")
    mount_point = tmp_dir / "mnt"
    mount_point.mkdir(exist_ok=True)

    # 挂载 dmg
    _run([
        "hdiutil", "attach", str(pkg_path),
        "-mountpoint", str(mount_point),
        "-nobrowse",   # 不在 Finder 中显示
        "-quiet",
    ])

    try:
        # 查找 .app 文件
        app_src = None
        for item in mount_point.iterdir():
            if item.name.endswith(".app"):
                app_src = item
                break

        if app_src is None:
            # 尝试在子目录中查找
            app_files = list(mount_point.rglob("*.app"))
            if app_files:
                app_src = app_files[0]

        if app_src is None:
            _log_and_print("❌ Could not find .app in the mounted disk image.", logging.ERROR)
            return

        app_dest = Path(QB_INSTALL_DIR) / app_src.name
        _log_and_print(f"📦 Copying {app_src.name} to {QB_INSTALL_DIR}...")

        # 如果目标已存在，先删除
        if app_dest.exists():
            _log_and_print(f"🗑️  Removing existing {app_dest}...")
            shutil.rmtree(str(app_dest))

        # 使用 cp -R 拷贝（保留权限和符号链接）
        _run(["cp", "-R", str(app_src), str(app_dest)])
        _log_and_print(f"✅ Copied to {app_dest}")

    finally:
        # 卸载 dmg
        _log_and_print("📦 Unmounting disk image...")
        _run(["hdiutil", "detach", str(mount_point), "-quiet"], check=False)


# ---------------------------------------------------------------------------
# Public API
# ---------------------------------------------------------------------------

def install(dry_run: bool = False, log_dir: str | None = None, force: bool = False) -> bool:
    """安装 QQ Browser（macOS 版）。

    Args:
        dry_run: 如果为 True，仅打印将要执行的操作，不实际安装。
        log_dir: 日志目录。
        force: 如果为 True，即使已安装也强制重新安装。

    Returns:
        True 表示安装后 QQ Browser 可用。
    """
    from .constants import DEFAULT_LOG_DIR
    if log_dir is None:
        log_dir = DEFAULT_LOG_DIR

    _setup_install_logging(log_dir)

    try:
        return _install_inner(dry_run, force=force)
    finally:
        _teardown_install_logging()


def _install_inner(dry_run: bool, force: bool = False) -> bool:
    """核心安装逻辑。"""
    _check_platform()

    # 检查是否已安装（force 模式下跳过检查，强制重装）
    if not force and is_installed():
        _log_and_print(f"✅ QQ Browser already installed: {QB_INSTALL_DIR}/{QB_APP_NAME}, skipping...")
        return True

    if force and is_installed():
        _log_and_print(f"🔄 QQ Browser already installed: {QB_INSTALL_DIR}/{QB_APP_NAME}, force reinstalling...")

    if dry_run:
        _log_and_print(f"🔍 [dry-run] Would download: {BASE_URL}/{QB_DMG}")
        _log_and_print("🔍 [dry-run] Would mount .dmg and copy .app to /Applications")
        return True

    # 在临时目录中下载并安装
    tmp_dir = Path(tempfile.mkdtemp(prefix="qqbrowser-install-"))
    try:
        _install_dmg(tmp_dir)
    except subprocess.CalledProcessError as exc:
        _log_and_print(f"❌ Installation command failed (exit code {exc.returncode}).", logging.ERROR)
        logger.error("Install failed: %s", exc)
        return False
    except Exception as exc:
        _log_and_print(f"❌ Installation failed: {exc}", logging.ERROR)
        logger.error("Install failed: %s", exc)
        return False
    finally:
        # 清理临时目录
        shutil.rmtree(tmp_dir, ignore_errors=True)

    # 验证安装结果
    if not is_installed():
        _log_and_print("❌ QQ Browser installation failed: application not found in /Applications.", logging.ERROR)
        _log_and_print("   Please try installing QQ Browser manually from https://browser.qq.com/", logging.ERROR)
        return False

    _log_and_print(f"✅ QQ Browser installed successfully: {QB_INSTALL_DIR}/{QB_APP_NAME}")
    return True
