#!/usr/bin/env python3
"""
Subtitle Font Manager · 字幕字体管理器
==========================​============
固定项目字幕字体，不能依赖系统默认字体。

功能：
  1. 检查项目字体是否已安装
  2. 如果未安装，自动下载/复制到项目字体目录
  3. 生成字体配置文件（供 ASS 渲染器使用）
  4. 验证字体文件是否有效（支持中文）

依赖：
  pip install fonttools  # 可选，用于验证字体
  # macOS: 系统字体通常在 /System/Library/Fonts/
  # Ubuntu: 系统字体通常在 /usr/share/fonts/

用法：
  # 检查并安装项目字体
  python subtitle-font-manager.py --check --install

  # 列出可用的中文字体
  python subtitle-font-manager.py --list

  # 设置项目字体
  python subtitle-font-manager.py --set-font "PingFang SC" --output project-font.json

  # 验证字体文件是否有效
  python subtitle-font-manager.py --validate ./assets/fonts/PingFangSC-Regular.otf

  # 生成 FFmpeg 字体路径配置
  python subtitle-font-manager.py --generate-ffmpeg-config --output ffmpeg-font.conf

输出：
  - project-font.json: 项目字体配置
  - ./assets/fonts/: 项目字体文件（如果需要下载）
  - ffmpeg-font.conf: FFmpeg 字体配置

路径：
  video-ai-system/engines/subtitle-pipeline/font-manager/subtitle-font-manager.py
"""

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

# 尝试导入 fonttools（可选）
try:
    from fonttools import TTFont
    from fonttools.unicode import Unicode
    FONTTOOLS_AVAILABLE = True
except ImportError:
    FONTTOOLS_AVAILABLE = False
    print("[WARN] 未安装 fonttools，将无法验证字体是否支持中文")


# 项目中文字体候选列表（按优先级排序）
CHINESE_FONT_CANDIDATES = [
    {
        "name": "PingFang SC",
        "mac_path": "/System/Library/Fonts/PingFang.ttc",
        "windows_path": "C:/Windows/Fonts/pingfang.ttc",
        "linux_path": "/usr/share/fonts/truetype/pingfang/PingFangSC-Regular.otf",
        "download_url": None,  # macOS 系统自带，无需下载
        "weight": "Regular"
    },
    {
        "name": "Hiragino Sans GB",
        "mac_path": "/System/Library/Fonts/Hiragino Sans GB.ttc",
        "windows_path": "C:/Windows/Fonts/hiragino.ttc",
        "linux_path": "/usr/share/fonts/truetype/hiragino/HiraginoSansGB-Regular.otf",
        "download_url": None,
        "weight": "Regular"
    },
    {
        "name": "Noto Sans CJK SC",
        "mac_path": "/System/Library/Fonts/Supplemental/Noto Sans CJK SC.ttc",
        "windows_path": "C:/Windows/Fonts/NotoSansCJK-Regular.ttc",
        "linux_path": "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc",
        "download_url": "https://github.com/googlefonts/noto-cjk/raw/main/Sans/OTF/SimplifiedChinese/NotoSansCJKsc-Regular.otf",
        "weight": "Regular"
    },
    {
        "name": "Source Han Sans SC",
        "mac_path": "/System/Library/Fonts/Supplemental/Source Han Sans SC.ttc",
        "windows_path": "C:/Windows/Fonts/SourceHanSansSC-Regular.otf",
        "linux_path": "/usr/share/fonts/opentype/source-han-sans/SourceHanSansSC-Regular.otf",
        "download_url": "https://github.com/adobe-fonts/source-han-sans/raw/release/OTF/SimplifiedChinese/SourceHanSansSC-Regular.otf",
        "weight": "Regular"
    },
    {
        "name": "WenQuanYi Micro Hei",
        "mac_path": None,
        "windows_path": None,
        "linux_path": "/usr/share/fonts/truetype/wqy/wqy-microhei.ttc",
        "download_url": "https://github.com/anthonyfok/fonts-wqy-microhei/raw/master/wqy-microhei.ttc",
        "weight": "Regular"
    }
]


def find_font_file(font_info: dict) -> str:
    """
    查找字体文件（跨平台）
    
    :param font_info: 字体信息字典
    :return: 字体文件路径，如果未找到返回 None
    """
    import platform
    system = platform.system()
    
    if system == "Darwin":  # macOS
        font_path = font_info.get("mac_path")
    elif system == "Windows":
        font_path = font_info.get("windows_path")
    elif system == "Linux":
        font_path = font_info.get("linux_path")
    else:
        font_path = None
    
    if font_path and os.path.isfile(font_path):
        return font_path
    
    return None


def check_chinese_support(font_path: str) -> bool:
    """
    检查字体是否支持中文（简体）
    
    :param font_path: 字体文件路径
    :return: 是否支持中文
    """
    if not FONTTOOLS_AVAILABLE:
        print("[WARN] 未安装 fonttools，跳过中文支持检查")
        return True
    
    try:
        font = TTFont(font_path)
        
        # 检查是否包含常用简体中文字符（GB2312 范围）
        # GB2312 一级汉字：0x4E00-0x9FA5
        chinese_chars = [chr(code) for code in range(0x4E00, 0x9FA5)]
        
        # 抽样检查（检查前100个常用汉字）
        sample_chars = chinese_chars[:100]
        
        supported = 0
        for char in sample_chars:
            if char in font:
                supported += 1
        
        support_ratio = supported / len(sample_chars)
        print(f"[INFO] 字体中文支持率：{support_ratio*100:.1f}%")
        
        return support_ratio > 0.8  # 支持率 > 80% 认为支持中文
    
    except Exception as e:
        print(f"[ERROR] 检查字体中文支持失败：{e}")
        return False


def install_font_to_project(font_info: dict, project_fonts_dir: str) -> str:
    """
    安装字体到项目字体目录
    
    :param font_info: 字体信息字典
    :param project_fonts_dir: 项目字体目录
    :return: 安装后的字体文件路径
    """
    os.makedirs(project_fonts_dir, exist_ok=True)
    
    # 查找系统字体文件
    system_font_path = find_font_file(font_info)
    
    if not system_font_path:
        print(f"[ERROR] 未找到系统字体：{font_info['name']}")
        if font_info.get("download_url"):
            print(f"[INFO] 尝试从以下地址下载：{font_info['download_url']}")
            # TODO: 实现下载逻辑
            return None
        else:
            print(f"[ERROR] 该字体无下载地址，请手动安装")
            return None
    
    # 复制到项目字体目录
    font_filename = os.path.basename(system_font_path)
    project_font_path = os.path.join(project_fonts_dir, font_filename)
    
    if not os.path.isfile(project_font_path):
        try:
            shutil.copy2(system_font_path, project_font_path)
            print(f"[OK] 字体已复制到项目目录：{project_font_path}")
        except Exception as e:
            print(f"[ERROR] 复制字体失败：{e}")
            return None
    else:
        print(f"[INFO] 字体已存在于项目目录：{project_font_path}")
    
    return project_font_path


def generate_project_font_config(font_path: str, output_path: str, font_name: str = None):
    """
    生成项目字体配置文件
    
    :param font_path: 字体文件路径
    :param output_path: 输出配置文件路径
    :param font_name: 字体名称（如果不指定，从文件读取）
    """
    # 如果未指定字体名称，尝试从文件读取
    if not font_name and FONTTOOLS_AVAILABLE:
        try:
            font = TTFont(font_path)
            font_name = font.get("name").getDebugName(4)  # 完整字体名称
        except Exception:
            font_name = os.path.splitext(os.path.basename(font_path))[0]
    
    config = {
        "_comment": "项目字幕字体配置",
        "font_name": font_name or "Unknown",
        "font_path": os.path.abspath(font_path),
        "font_path_relative": os.path.relpath(font_path, os.path.dirname(output_path)),
        "install_date": __import__("datetime").datetime.now().isoformat(),
        "supports_chinese": check_chinese_support(font_path) if FONTTOOLS_AVAILABLE else None,
        "ass_fontname": font_name,  # ASS 格式使用的字体名称
        "ffmpeg_font_path": font_path,  # FFmpeg 使用的字体路径
    }
    
    with open(output_path, "w", encoding="utf-8") as f:
        json.dump(config, f, ensure_ascii=False, indent=2)
    
    print(f"[OK] 项目字体配置已生成：{output_path}")


def list_available_fonts():
    """
    列出系统中可用的中文字体
    """
    print("\n[INFO] 查找系统中可用的中文字体...")
    
    available = []
    for font_info in CHINESE_FONT_CANDIDATES:
        font_path = find_font_file(font_info)
        if font_path:
            available.append({
                "name": font_info["name"],
                "path": font_path,
                "weight": font_info["weight"]
            })
            print(f"  ✅ {font_info['name']} ({font_info['weight']})")
            print(f"     路径：{font_path}")
        else:
            print(f"  ❌ {font_info['name']} (未找到)")
    
    if not available:
        print("\n[WARN] 未找到任何中文字体，请手动安装中文字体")
        print("推荐字体：")
        print("  - macOS: PingFang SC（系统自带）")
        print("  - Ubuntu: fonts-noto-cjk（apt install fonts-noto-cjk）")
        print("  - Windows: 微软雅黑（系统自带）")
    
    return available


def main():
    parser = argparse.ArgumentParser(
        description="Subtitle Font Manager · 字幕字体管理器",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
示例：
  python subtitle-font-manager.py --list
  python subtitle-font-manager.py --check --install
  python subtitle-font-manager.py --set-font "PingFang SC" --output project-font.json
  python subtitle-font-manager.py --validate ./assets/fonts/PingFangSC-Regular.otf
"""
    )
    parser.add_argument("--list", action="store_true", help="列出可用的中文字体")
    parser.add_argument("--check", action="store_true", help="检查项目字体是否已安装")
    parser.add_argument("--install", action="store_true", help="如果未安装，自动安装字体到项目目录")
    parser.add_argument("--set-font", help="设置项目字体（字体名称）")
    parser.add_argument("--output", help="输出配置文件路径")
    parser.add_argument("--validate", help="验证字体文件是否有效")
    parser.add_argument("--generate-ffmpeg-config", action="store_true", help="生成 FFmpeg 字体配置")
    parser.add_argument("--project-fonts-dir", default="./assets/fonts/", help="项目字体目录")
    
    args = parser.parse_args()
    
    if args.list:
        list_available_fonts()
        sys.exit(0)
    
    if args.validate:
        if not os.path.isfile(args.validate):
            print(f"[ERROR] 字体文件不存在：{args.validate}")
            sys.exit(1)
        
        print(f"[INFO] 验证字体文件：{args.validate}")
        supports_chinese = check_chinese_support(args.validate)
        
        if supports_chinese:
            print(f"[OK] 字体有效，支持中文")
        else:
            print(f"[WARN] 字体可能不支持中文，请手动检查")
        sys.exit(0)
    
    if args.check or args.install:
        # 检查项目字体是否已安装
        project_font_config = os.path.join(args.project_fonts_dir, "../subtitle-styles/project-font.json")
        project_font_config = os.path.abspath(project_font_config)
        
        if os.path.isfile(project_font_config):
            with open(project_font_config, "r", encoding="utf-8") as f:
                config = json.load(f)
            print(f"[INFO] 项目字体已配置：{config['font_name']}")
            print(f"[INFO] 字体路径：{config['font_path']}")
            
            if not os.path.isfile(config["font_path"]):
                print(f"[WARN] 字体文件不存在，需要重新安装")
                args.install = True
            else:
                sys.exit(0)
        
        if args.install:
            # 安装字体
            available = list_available_fonts()
            
            if not available:
                sys.exit(1)
            
            # 使用第一个可用的字体
            font_info = available[0]
            print(f"\n[INFO] 安装字体：{font_info['name']}")
            
            # 查找字体信息
            font_info_full = next((f for f in CHINESE_FONT_CANDIDATES if f["name"] == font_info["name"]), None)
            
            if font_info_full:
                project_font_path = install_font_to_project(font_info_full, args.project_fonts_dir)
                
                if project_font_path and args.output:
                    generate_project_font_config(project_font_path, args.output, font_info["name"])
    
    if args.set_font:
        # 设置项目字体
        font_info = next((f for f in CHINESE_FONT_CANDIDATES if f["name"] == args.set_font), None)
        
        if not font_info:
            print(f"[ERROR] 未找到字体：{args.set_font}")
            print(f"[INFO] 可用字体：{[f['name'] for f in CHINESE_FONT_CANDIDATES]}")
            sys.exit(1)
        
        project_font_path = install_font_to_project(font_info, args.project_fonts_dir)
        
        if project_font_path and args.output:
            generate_project_font_config(project_font_path, args.output, args.set_font)
    
    if args.generate_ffmpeg_config:
        # 生成 FFmpeg 字体配置
        # FFmpeg 可以使用 fontfile 滤镜指定字体文件
        output = args.output or "ffmpeg-font.conf"
        
        # 读取项目字体配置
        project_font_config = os.path.join(args.project_fonts_dir, "../subtitle-styles/project-font.json")
        project_font_config = os.path.abspath(project_font_config)
        
        if not os.path.isfile(project_font_config):
            print(f"[ERROR] 项目字体未配置，请先运行 --check --install")
            sys.exit(1)
        
        with open(project_font_config, "r", encoding="utf-8") as f:
            config = json.load(f)
        
        # 生成 FFmpeg 滤镜字符串
        font_path = config["font_path"]
        ffmpeg_filter = f"subtitles=subtitles.ass:force_style='FontName={config['font_name']},FontFile={font_path}'"
        
        with open(output, "w", encoding="utf-8") as f:
            f.write(f"# FFmpeg 字体配置\n")
            f.write(f"# 使用方法：ffmpeg -i input.mp4 -vf \"{ffmpeg_filter}\" output.mp4\n\n")
            f.write(f"font_path={font_path}\n")
            f.write(f"font_name={config['font_name']}\n")
            f.write(f"ffmpeg_filter={ffmpeg_filter}\n")
        
        print(f"[OK] FFmpeg 字体配置已生成：{output}")


if __name__ == "__main__":
    main()
