"""
服务器环境初始化脚本：删除 skip-worktree 排除的文件/目录 + 创建 export 目录树。

在服务器上 git clone + setup-server-git.py 之后运行。
1. 删除已被 skip-worktree 标记的目录和散文件（释放磁盘空间）
2. 创建完整的 export/ 目录树（ETL/SYSTEM/BACKEND 三大类）

用法:
    python scripts/server/init-server-env.py                # 初始化 test + prod（默认）
    python scripts/server/init-server-env.py --envs test     # 只初始化 test
    python scripts/server/init-server-env.py --envs prod     # 只初始化 prod
    python scripts/server/init-server-env.py --envs test prod
"""

import argparse
import os
import shutil
import sys
from pathlib import Path

# ============================================================================
# 配置
# ============================================================================

SERVER_ROOT = Path(r"D:\NeoZQYY")

ENV_PATHS: dict[str, Path] = {
    "test": SERVER_ROOT / "test" / "repo",
    "prod": SERVER_ROOT / "prod" / "repo",
}

# skip-worktree 后可安全删除的目录（与 setup-server-git.py DELETABLE_DIRS 一致）
DELETABLE_DIRS = [
    "export",
    "docs",
    "tests",
    "samples",
    "infra",
    ".kiro",
    ".hypothesis",
    ".pytest_cache",
    r"apps\miniprogram",
    r"scripts\ops",
    r"scripts\audit",
    r"scripts\migrate",
]

# 可安全删除的根目录散文件
DELETABLE_FILES = [
    "coach-detail-full.png",
    "customer-detail-full.png",
    "perf-records-current.png",
    "white-screen-debug.png",
    "NeoZQYY.code-workspace",
    "start-admin.bat",
    ".kiroignore",
]

# export 目录树（所有环境通用）
EXPORT_DIRS = [
    r"export\ETL-Connectors\feiqiu\JSON",
    r"export\ETL-Connectors\feiqiu\LOGS",
    r"export\ETL-Connectors\feiqiu\REPORTS",
    r"export\SYSTEM\LOGS",
    r"export\SYSTEM\REPORTS\dataflow_analysis",
    r"export\SYSTEM\REPORTS\field_audit",
    r"export\SYSTEM\REPORTS\full_dataflow_doc",
    r"export\SYSTEM\CACHE\api_samples",
    r"export\BACKEND\LOGS",
]


# ============================================================================
# 颜色输出（Windows 终端支持 ANSI）
# ============================================================================

class C:
    """ANSI 颜色码"""
    RED = "\033[91m"
    GREEN = "\033[92m"
    YELLOW = "\033[93m"
    CYAN = "\033[96m"
    MAGENTA = "\033[95m"
    WHITE = "\033[97m"
    GRAY = "\033[90m"
    RESET = "\033[0m"


def cprint(msg: str, color: str = C.WHITE) -> None:
    print(f"{color}{msg}{C.RESET}")


# ============================================================================
# 函数
# ============================================================================

def get_dir_size_mb(path: Path) -> float:
    """递归计算目录大小（MB）"""
    total = 0
    try:
        for f in path.rglob("*"):
            if f.is_file():
                total += f.stat().st_size
    except OSError:
        pass
    return round(total / (1024 * 1024), 1)


def get_file_size_mb(path: Path) -> float:
    try:
        return round(path.stat().st_size / (1024 * 1024), 2)
    except OSError:
        return 0.0


def remove_skip_worktree_items(repo_path: Path) -> None:
    """删除指定 repo 下已被 skip-worktree 标记的目录和散文件。"""
    cprint("\n  [删除] 清理 skip-worktree 排除的目录和文件...", C.YELLOW)
    freed_mb = 0.0

    # 删除目录
    for d in DELETABLE_DIRS:
        full = repo_path / d
        if full.exists() and full.is_dir():
            size = get_dir_size_mb(full)
            shutil.rmtree(full, ignore_errors=True)
            cprint(f"    已删除: {d}/ ({size} MB)", C.RED)
            freed_mb += size
        else:
            cprint(f"    跳过:   {d}/ (不存在)", C.GRAY)

    # 删除散文件
    for f in DELETABLE_FILES:
        full = repo_path / f
        if full.exists() and full.is_file():
            size = get_file_size_mb(full)
            full.unlink()
            cprint(f"    已删除: {f} ({size} MB)", C.RED)
            freed_mb += size

    # 删除根目录下所有 .png 文件
    for png in repo_path.glob("*.png"):
        if png.is_file():
            size = get_file_size_mb(png)
            png.unlink()
            cprint(f"    已删除: {png.name} ({size} MB)", C.RED)
            freed_mb += size

    cprint(f"    共释放: {freed_mb:.1f} MB", C.GREEN)


def create_export_tree(repo_path: Path) -> None:
    """在指定 repo 下创建完整的 export 目录树。"""
    cprint("\n  [创建] 初始化 export 目录树...", C.YELLOW)

    for d in EXPORT_DIRS:
        full = repo_path / d
        if not full.exists():
            full.mkdir(parents=True, exist_ok=True)
            cprint(f"    已创建: {d}/", C.CYAN)
        else:
            cprint(f"    已存在: {d}/", C.GRAY)


def test_git_setup(repo_path: Path) -> bool:
    """检查 setup-server-git.py 是否已运行。"""
    exclude_file = repo_path / ".git" / "info" / "exclude"
    if not exclude_file.exists():
        return False
    try:
        content = exclude_file.read_text(encoding="utf-8", errors="ignore")
        return "server-exclude" in content
    except OSError:
        return False


# ============================================================================
# 主流程
# ============================================================================

def main() -> None:
    parser = argparse.ArgumentParser(description="NeoZQYY 服务器环境初始化")
    parser.add_argument(
        "--envs",
        nargs="+",
        default=["test", "prod"],
        choices=["test", "prod"],
        help="要初始化的环境列表（默认: test prod）",
    )
    args = parser.parse_args()

    # Windows 终端启用 ANSI 颜色
    if sys.platform == "win32":
        os.system("")  # 触发 ANSI 支持

    cprint("=" * 44, C.WHITE)
    cprint(" NeoZQYY 服务器环境初始化", C.WHITE)
    cprint(f" 目标环境: {', '.join(args.envs)}", C.WHITE)
    cprint("=" * 44, C.WHITE)

    for env in args.envs:
        repo_path = ENV_PATHS.get(env)
        if not repo_path:
            cprint(f"\n[错误] 未知环境: {env}（可选: test, prod）", C.RED)
            continue

        cprint(f"\n{'=' * 10} 环境: {env} {'=' * 10}", C.MAGENTA)
        cprint(f"  路径: {repo_path}")

        # 检查 repo 是否存在
        if not repo_path.exists():
            cprint("  [警告] 目录不存在，跳过。请先 git clone。", C.YELLOW)
            continue

        # 检查 setup-server-git.py 是否已运行
        if not test_git_setup(repo_path):
            cprint("  [警告] 未检测到 setup-server-git.py 的配置。", C.YELLOW)
            cprint("         建议先运行: python scripts/server/setup-server-git.py", C.YELLOW)
            answer = input("  是否继续删除操作？(y/N) ").strip()
            if answer.lower() != "y":
                cprint(f"  已跳过 {env} 环境的删除操作。", C.GRAY)
                # 仍然创建 export 目录
                create_export_tree(repo_path)
                continue

        # 步骤 1：删除排除的文件/目录
        remove_skip_worktree_items(repo_path)

        # 步骤 2：创建 export 目录树
        create_export_tree(repo_path)

        cprint(f"\n  [完成] {env} 环境初始化完毕。", C.GREEN)

    cprint("\n" + "=" * 44, C.WHITE)
    cprint(" 全部完成。", C.GREEN)
    print()
    cprint(" 后续步骤:", C.WHITE)
    cprint("   1. 手动创建各环境的 .env 文件（参考 .env.template）", C.WHITE)
    cprint("   2. 确认 .env 中的 export 路径指向 repo/export/ 下对应子目录", C.WHITE)
    cprint("   3. 运行 uv sync --all-packages 安装依赖", C.WHITE)
    cprint("=" * 44, C.WHITE)


if __name__ == "__main__":
    main()
