#!/usr/bin/env python3
"""
Bing 必应壁纸获取脚本
- 获取当日最高清壁纸并保存到"壁纸历史"文件夹
- 自动设置为 Deepin/DDE 桌面壁纸
- 如果今日壁纸已获取过，则获取随机历史壁纸

API 来源: https://bing.img.run/api.html
"""

import os
import sys
import subprocess
import datetime
import glob

# ---- 配置 ----
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
SAVE_DIR = os.path.join(SCRIPT_DIR, "壁纸历史")
TODAY_API = "https://bing.img.run/uhd.php"        # 今日 UHD 超高清
RANDOM_API = "https://bing.img.run/rand_uhd.php"  # 随机 UHD 超高清


def get_url_info(url):
    """获取重定向后的最终 URL 和 Content-Type"""
    result = subprocess.run(
        ["curl", "-sL", "-o", "/dev/null", "-w", "%{url_effective}\n%{content_type}", url],
        capture_output=True, text=True, timeout=30
    )
    lines = result.stdout.strip().split("\n")
    final_url = lines[0] if lines else ""
    content_type = lines[1] if len(lines) > 1 else ""
    return final_url, content_type


def guess_extension(content_type, final_url):
    """从 Content-Type 或 URL 中推测文件扩展名"""
    ct = content_type.lower()
    if "png" in ct:
        return ".png"
    if "webp" in ct:
        return ".webp"
    if "jpeg" in ct or "jpg" in ct:
        return ".jpg"

    url_lower = final_url.lower()
    for ext in (".jpg", ".jpeg", ".png", ".webp"):
        if ext in url_lower:
            return ext
    return ".jpg"


def download(url, filepath):
    """下载图片到指定路径"""
    subprocess.run(
        ["curl", "-sL", "-o", filepath, url],
        check=True, timeout=60
    )


def get_monitor_names():
    """获取所有已连接的显示器名称列表 (DDE dbus)"""
    result = subprocess.run(
        ["gdbus", "call", "--session",
         "--dest", "org.deepin.dde.Display1",
         "--object-path", "/org/deepin/dde/Display1",
         "--method", "org.deepin.dde.Display1.ListOutputNames"],
        capture_output=True, text=True, timeout=5
    )
    if result.returncode != 0:
        return []

    # 解析返回值: (['eDP', 'HDMI-1-0'],)
    raw = result.stdout.strip()
    # 提取括号内的数组部分
    if "[" in raw and "]" in raw:
        arr_str = raw[raw.index("[") + 1:raw.index("]")]
        monitors = [m.strip().strip("'").strip('"') for m in arr_str.split(",") if m.strip()]
        return monitors
    return []


def get_builtin_monitor_name():
    """获取内置显示器名称（笔记本屏幕，如 eDP），失败返回 None"""
    result = subprocess.run(
        ["gdbus", "call", "--session",
         "--dest", "org.deepin.dde.Display1",
         "--object-path", "/org/deepin/dde/Display1",
         "--method", "org.deepin.dde.Display1.GetBuiltinMonitor"],
        capture_output=True, text=True, timeout=5
    )
    if result.returncode != 0:
        return None
    # 返回值: ('eDP', objectpath '/org/deepin/dde/Display1/Monitor_83')
    raw = result.stdout.strip()
    if raw.startswith("('"):
        name = raw.split("'")[1]
        return name
    return None


def set_one_monitor(uri, monitor_name):
    """为单个显示器设置壁纸"""
    result = subprocess.run(
        ["gdbus", "call", "--session",
         "--dest", "org.deepin.dde.Appearance1",
         "--object-path", "/org/deepin/dde/Appearance1",
         "--method", "org.deepin.dde.Appearance1.SetCurrentWorkspaceBackgroundForMonitor",
         uri, monitor_name],
        capture_output=True, text=True, timeout=10
    )
    return result.returncode == 0


def set_wallpaper(filepath):
    """
    设置桌面壁纸:
    - 多屏幕时，仅设置主屏（内置屏幕，如笔记本 eDP）
    - 单屏幕时，无论类型都设置
    """
    abs_path = os.path.abspath(filepath)
    uri = f"file://{abs_path}"

    monitors = get_monitor_names()
    builtin = get_builtin_monitor_name()

    # 决定要设置的目标显示器
    if len(monitors) > 1:
        # 多屏：仅主屏
        if builtin and builtin in monitors:
            targets = [builtin]
        else:
            # 没有内置屏幕（台式机多屏），取第一个作为主屏
            targets = [monitors[0]]
        print(f"🖥️  检测到 {len(monitors)} 个屏幕，仅设置主屏")
    elif len(monitors) == 1:
        # 单屏：直接设置
        targets = monitors
    else:
        # 无法获取显示器，回退
        print("⚠️  无法获取显示器列表，尝试通用设置...")
        result = subprocess.run(
            ["gdbus", "call", "--session",
             "--dest", "org.deepin.dde.Appearance1",
             "--object-path", "/org/deepin/dde/Appearance1",
             "--method", "org.deepin.dde.Appearance1.SetCurrentWorkspaceBackground",
             uri],
            capture_output=True, text=True, timeout=10
        )
        if result.returncode == 0:
            print(f"🖥️  壁纸已设置")
        else:
            print(f"❌ 壁纸设置失败: {result.stderr.strip()}")
        return

    for monitor in targets:
        if set_one_monitor(uri, monitor):
            print(f"🖥️  壁纸已设置 → {monitor}")
        else:
            print(f"❌ {monitor} 壁纸设置失败")


def main():
    today_str = datetime.date.today().strftime("%Y-%m-%d")

    # 按日期创建子文件夹: 壁纸历史/2026-06-12/
    today_dir = os.path.join(SAVE_DIR, today_str)
    os.makedirs(today_dir, exist_ok=True)

    # 检查今日子文件夹内是否已有壁纸
    existing = glob.glob(os.path.join(today_dir, "*"))

    if existing:
        print(f"📌 今日已获取过 {len(existing)} 张壁纸")
        print("🎲 改为获取随机历史壁纸...")
        api_url = RANDOM_API
        # 随机壁纸加时间戳，避免覆盖
        ts = datetime.datetime.now().strftime("%H%M%S")
        prefix = f"{today_str}_random_{ts}"
    else:
        print("📥 获取今日必应壁纸 (UHD 超高清)...")
        api_url = TODAY_API
        prefix = today_str

    # 获取目标文件信息
    final_url, content_type = get_url_info(api_url)
    ext = guess_extension(content_type, final_url)

    filename = f"{prefix}{ext}"
    filepath = os.path.join(today_dir, filename)

    # 下载
    print("⬇️  下载中...")
    download(api_url, filepath)

    # 校验
    if not os.path.exists(filepath) or os.path.getsize(filepath) == 0:
        print("❌ 下载失败，请检查网络连接")
        sys.exit(1)

    size_kb = os.path.getsize(filepath) / 1024
    print(f"💾 已保存: 壁纸历史/{today_str}/{filename}  ({size_kb:.1f} KB)")

    # 设为壁纸
    set_wallpaper(filepath)


if __name__ == "__main__":
    main()
