"""将用户选中的 .lnk / .url 解析为实际要存储的路径（目标程序或 URL）。"""
import base64
import json
import os
import re
import subprocess
import sys


def _looks_like_shell_lnk(path: str) -> bool:
    """Windows Shell Link 文件头为 4C 00 00 00（扩展名异常时仍可识别）。"""
    try:
        with open(path, "rb") as f:
            return f.read(4) == b"L\x00\x00\x00"
    except OSError:
        return False


def _read_internet_shortcut_url(path: str) -> str | None:
    try:
        with open(path, "r", encoding="utf-8", errors="ignore") as f:
            for line in f:
                s = line.strip()
                if s[:4].upper() == "URL=":
                    return s[4:].strip()
    except OSError:
        pass
    return None


def _resolve_windows_lnk(lnk_path: str) -> str | None:
    if sys.platform != "win32":
        return None
    env = os.environ.copy()
    env["LNK_B64"] = base64.b64encode(os.path.normpath(lnk_path).encode("utf-8")).decode(
        "ascii"
    )
    ps = (
        "$p=[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($env:LNK_B64));"
        "$sc=(New-Object -ComObject WScript.Shell).CreateShortcut($p);"
        "@{ t=[string]$sc.TargetPath; a=[string]$sc.Arguments }|ConvertTo-Json -Compress"
    )
    try:
        r = subprocess.run(
            [
                "powershell",
                "-NoProfile",
                "-Sta",
                "-Command",
                ps,
            ],
            capture_output=True,
            text=True,
            encoding="utf-8",
            errors="replace",
            env=env,
            timeout=15,
            creationflags=getattr(subprocess, "CREATE_NO_WINDOW", 0),
        )
        raw = (r.stdout or "").strip().lstrip("\ufeff")
        if not raw:
            return None
        data = json.loads(raw)
        target = (data.get("t") or "").strip()
        args = (data.get("a") or "").strip()
        if not target:
            return None
        low = target.lower()
        if low.endswith("cmd.exe") or low.endswith("\\cmd.exe"):
            for m in re.finditer(
                r"([a-zA-Z]:[^\"'\s]+\.(?:bat|cmd))|\x22([a-zA-Z]:[^\"]+\.(?:bat|cmd))\x22",
                args,
                re.IGNORECASE,
            ):
                cand = (m.group(1) or m.group(2) or "").strip('"')
                if cand and os.path.isfile(cand):
                    return os.path.normpath(cand)
        if os.path.isfile(target) or low.startswith("\\\\"):
            return os.path.normpath(target)
        return os.path.normpath(target)
    except Exception:
        return None


def path_for_storage(local_path: str) -> str:
    """
    拖拽/选择文件时写入数据库的 path：.lnk/.url 解析为目标，其它保持原路径。
    解析失败时退回本地路径。
    """
    if not local_path:
        return local_path
    local_path = os.path.normpath(local_path.strip())

    ext = os.path.splitext(local_path)[1].lower()
    if ext == ".url":
        try:
            if os.path.isfile(local_path):
                url = _read_internet_shortcut_url(local_path)
                if url:
                    return url
        except (OSError, ValueError):
            pass
        return local_path

    try:
        is_file = os.path.isfile(local_path)
    except (OSError, ValueError):
        is_file = False

    is_lnk = ext in (".lnk", ".ink") or (
        is_file and _looks_like_shell_lnk(local_path)
    )
    if is_lnk and is_file:
        resolved = _resolve_windows_lnk(local_path)
        if resolved:
            return resolved
    return local_path


def item_name_from_sources(local_path: str, store_path: str) -> str:
    """列表显示名：仍用快捷方式/所选文件的文件名（无扩展名），与原来行为一致。"""
    base = os.path.splitext(os.path.basename(local_path))[0]
    return base or os.path.basename(store_path)
