import os
import datetime
from pathlib import Path
from typing import Dict


def save_face_to_up_images(
        client_ip: str,
        face_name: str,
        image_bytes: bytes,
        image_format: str = "jpg"
) -> Dict[str, str]:
    """
    保存人脸图片到 `/up_images/用户IP/人脸名字/` 路径
    确保db_path以up_images开头，且统一使用正斜杠

    参数:
        client_ip: 客户端IP（原始格式，如192.168.1.101）
        face_name: 人脸名称（用户输入，可为空）
        image_bytes: 人脸图片二进制数据
        image_format: 图片格式（默认jpg）

    返回:
        字典：success（是否成功）、db_path（存数据库的相对路径）、local_abs_path（本地绝对路径）、msg（提示）
    """
    try:
        # 1. 基础参数校验
        if not client_ip.strip():
            return {"success": False, "db_path": "", "local_abs_path": "", "msg": "客户端IP不能为空"}
        if not image_bytes:
            return {"success": False, "db_path": "", "local_abs_path": "", "msg": "图片二进制数据为空"}
        if image_format.lower() not in ["jpg", "jpeg", "png"]:
            return {"success": False, "db_path": "", "local_abs_path": "", "msg": "仅支持jpg/jpeg/png格式"}

        # 2. 处理特殊字符（避免路径错误）
        safe_ip = client_ip.strip().replace(".", "_")  # IP中的.替换为_
        safe_face_name = face_name.strip() if (face_name and face_name.strip()) else "未命名"
        safe_face_name = "".join([c for c in safe_face_name if c not in r'\/:*?"<>|'])  # 过滤非法字符

        # 3. 构建根目录（强制转为绝对路径，避免相对路径混淆）
        root_dir = Path("up_images").resolve()  # 转为绝对路径（如D:/Git/bin/video/up_images）
        if not root_dir.exists():
            root_dir.mkdir(parents=True, exist_ok=True)
            print(f"[FileUtil] 已创建up_images根目录：{root_dir}")

        # 4. 构建文件层级路径（确保在root_dir子目录下）
        ip_dir = root_dir / safe_ip
        face_name_dir = ip_dir / safe_face_name
        face_name_dir.mkdir(parents=True, exist_ok=True)  # 自动创建目录
        print(f"[FileUtil] 图片存储目录：{face_name_dir}")

        # 5. 生成唯一文件名（毫秒级时间戳）
        timestamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S%f")[:-3]
        image_filename = f"face_{safe_ip}_{timestamp}.{image_format.lower()}"

        # 6. 计算路径（确保所有路径都是绝对路径且在root_dir下）
        local_abs_path = face_name_dir / image_filename  # 绝对路径

        # 验证路径是否在root_dir下（防止路径穿越攻击）
        if not local_abs_path.resolve().is_relative_to(root_dir.resolve()):
            raise Exception(f"图片路径不在up_images根目录下（安全校验失败）：{local_abs_path}")

        # 数据库存储路径：强制包含up_images前缀，统一使用正斜杠
        relative_path = local_abs_path.relative_to(root_dir.parent)  # 相对于root_dir的父目录
        db_path = str(relative_path).replace("\\", "/")  # 此时会包含up_images部分

        # 7. 写入图片文件
        with open(local_abs_path, "wb") as f:
            f.write(image_bytes)
        print(f"[FileUtil] 图片保存成功：")
        print(f"  数据库路径：{db_path}")
        print(f"  本地绝对路径：{local_abs_path}")

        return {
            "success": True,
            "db_path": db_path,  # 格式为 up_images/192_168_110_31/小龙/xxx.jpg
            "local_abs_path": str(local_abs_path),  # 本地绝对路径（完整路径）
            "msg": "图片保存成功"
        }

    except Exception as e:
        error_msg = f"图片保存失败：{str(e)}"
        print(f"[FileUtil] 错误：{error_msg}")
        return {"success": False, "db_path": "", "local_abs_path": "", "msg": error_msg}
