"""
路径解析模块 — 兼容开发模式与 PyInstaller EXE 模式

PyInstaller --onedir 打包时：
- sys._MEIPASS = EXE 目录下的 _internal/ 子目录（只读资源，与 EXE 同目录）
- sys.executable = EXE 文件路径
- 只读资源（模板、前端、提示词、代码）→ 优先 EXE 目录下的 bff-api/（升级包覆盖）
                                         → 兜底 _internal/（onedir 内置）
- 可写资源（数据库、上传、导出、.env）→ 优先从数据分区读取（U盘双分区模式）
                                         → 兜底从 EXE 所在目录读取（单分区模式）
"""
import os
import sys
import logging

logger = logging.getLogger(__name__)

# 数据分区路径缓存
_data_dir_cache: str | None = None


def is_frozen() -> bool:
    """是否为 PyInstaller 打包后的 EXE 运行模式"""
    return getattr(sys, 'frozen', False)


def get_exe_dir() -> str:
    """
    获取 EXE 所在目录（程序文件根目录）

    开发模式：项目根目录（d:\danjiban\）
    EXE 模式：EXE 文件所在目录
    """
    if is_frozen():
        return os.path.dirname(sys.executable)
    else:
        # 开发模式：paths.py 在 bff-api/app/core/ 下，向上 4 层到项目根目录
        return os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))


def get_data_dir() -> str:
    """
    获取可写数据目录（数据库、上传、导出、日志等）

    双分区 U 盘模式：数据分区（通过 .zfzs_data 标记文件自动检测）
    单分区模式/开发模式：与 EXE 目录相同

    检测逻辑：
    1. 环境变量 ZFZS_DATA_DIR（最高优先级，可手动指定）
    2. EXE 目录下 .zfzs_data 文件存在 → EXE 目录本身就是数据目录
    3. 扫描其他驱动器查找 .zfzs_data 标记 → 双分区模式
    4. 都没找到 → 降级为 EXE 目录（兼容单机版）
    """
    global _data_dir_cache
    if _data_dir_cache is not None:
        return _data_dir_cache

    # 1. 环境变量
    env_dir = os.environ.get("ZFZS_DATA_DIR", "").strip()
    if env_dir and os.path.isdir(env_dir):
        _data_dir_cache = env_dir
        logger.info(f"数据目录（环境变量）: {_data_dir_cache}")
        return _data_dir_cache

    exe_dir = get_exe_dir()

    # 2. EXE 目录本身就是数据目录（单分区模式）
    if os.path.exists(os.path.join(exe_dir, ".zfzs_data")):
        _data_dir_cache = exe_dir
        logger.info(f"数据目录（单分区）: {_data_dir_cache}")
        return _data_dir_cache

    # 3. 扫描其他驱动器查找数据分区标记（双分区模式）
    if is_frozen():
        exe_drive = os.path.splitdrive(exe_dir)[0].upper()
        for letter in "DEFGHIJKLMNOPQRSTUVWXYZ":
            if letter == exe_drive:
                continue
            marker = f"{letter}:\\.zfzs_data"
            if os.path.exists(marker):
                _data_dir_cache = f"{letter}:\\"
                logger.info(f"数据目录（双分区，数据分区）: {_data_dir_cache}")
                return _data_dir_cache

    # 4. 降级：EXE 目录
    _data_dir_cache = exe_dir
    logger.info(f"数据目录（降级）: {_data_dir_cache}")
    return _data_dir_cache


def _local_bff_dir() -> str | None:
    """EXE 模式下，检查 EXE 目录下是否有本地更新的 bff-api/"""
    if not is_frozen():
        return None
    exe_dir = os.path.dirname(sys.executable)
    local_bff = os.path.join(exe_dir, "bff-api")
    return local_bff if os.path.exists(local_bff) else None


def get_resource_dir() -> str:
    """
    获取只读资源根目录

    开发模式：bff-api 目录（d:\danjiban\bff-api\）
    EXE 模式（onedir）：优先 EXE 目录下的 bff-api/（升级包覆盖），兜底 _internal/（sys._MEIPASS）
    """
    if is_frozen():
        local = _local_bff_dir()
        return local if local else sys._MEIPASS
    else:
        return os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))


def get_bff_api_dir() -> str:
    """
    获取 bff-api 目录

    开发模式：bff-api 目录
    EXE 模式：优先 EXE 目录下的 bff-api/（升级包覆盖），兜底 _MEIPASS
    """
    if is_frozen():
        local = _local_bff_dir()
        return local if local else sys._MEIPASS
    else:
        return os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))


def resolve_writable_path(relative_path: str) -> str:
    """
    解析可写文件路径（数据库、上传、导出等）
    双分区模式：相对于数据分区
    单分区模式：相对于 EXE 所在目录
    """
    if os.path.isabs(relative_path):
        return relative_path
    return os.path.normpath(os.path.join(get_data_dir(), relative_path))


def resolve_resource_path(relative_path: str) -> str:
    """
    解析只读资源路径（模板、前端、提示词等）
    开发模式：相对于项目根目录
    EXE 模式：相对于 _MEIPASS
    """
    if os.path.isabs(relative_path):
        return relative_path
    return os.path.normpath(os.path.join(get_resource_dir(), relative_path))