#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
批量将 Markdown 文件转换为 DOCX 格式

使用 pandoc 工具进行转换，支持递归遍历目录。
"""

import argparse
import os
import subprocess
import sys
from pathlib import Path
from typing import List, Optional


def find_markdown_files(directory: str, recursive: bool = True) -> List[Path]:
    """
    查找目录下所有的 Markdown 文件

    Args:
        directory: 要搜索的目录路径
        recursive: 是否递归搜索子目录

    Returns:
        Markdown 文件路径列表
    """
    directory_path = Path(directory)

    if not directory_path.exists():
        print(f"错误: 目录不存在: {directory}")
        return []

    if not directory_path.is_dir():
        print(f"错误: 不是一个目录: {directory}")
        return []

    if recursive:
        # 递归查找所有 .md 文件
        md_files = list(directory_path.rglob("*.md"))
    else:
        # 只查找当前目录的 .md 文件
        md_files = list(directory_path.glob("*.md"))

    return md_files


def convert_md_to_docx(
    md_file: Path,
    output_dir: Optional[str] = None,
    overwrite: bool = False,
    pandoc_args: List[str] = None
) -> bool:
    """
    将单个 Markdown 文件转换为 DOCX

    Args:
        md_file: Markdown 文件路径
        output_dir: 输出目录（None 表示与源文件同目录）
        overwrite: 是否覆盖已存在的文件
        pandoc_args: 额外的 pandoc 参数

    Returns:
        转换是否成功
    """
    # 确定输出文件路径
    if output_dir:
        output_path = Path(output_dir) / f"{md_file.stem}.docx"
        # 确保输出目录存在
        output_path.parent.mkdir(parents=True, exist_ok=True)
    else:
        output_path = md_file.with_suffix(".docx")

    # 检查输出文件是否已存在
    if output_path.exists() and not overwrite:
        print(f"跳过 (文件已存在): {md_file} -> {output_path}")
        return True

    # 构建 pandoc 命令
    cmd = [
        "pandoc",
        "--from=markdown-tex_math_dollars",  # 禁用数学公式解析
        str(md_file),
        "-o",
        str(output_path)
    ]

    # 添加额外的 pandoc 参数
    if pandoc_args:
        cmd.extend(pandoc_args)

    try:
        print(f"转换中: {md_file} -> {output_path}")
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,
            check=True,
            encoding='utf-8'
        )
        print(f"成功: {output_path}")
        return True
    except subprocess.CalledProcessError as e:
        print(f"错误: 转换失败 {md_file}")
        print(f"  命令: {' '.join(cmd)}")
        if e.stderr:
            print(f"  错误信息: {e.stderr}")
        return False
    except FileNotFoundError:
        print("错误: 未找到 pandoc 命令，请确保已安装 pandoc")
        print("  安装方法: https://pandoc.org/installing.html")
        sys.exit(1)


def main():
    """主函数"""
    parser = argparse.ArgumentParser(
        description="批量将 Markdown 文件转换为 DOCX 格式",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
示例用法:
  # 转换指定目录下所有 .md 文件（递归）
  python convert_md_to_docx.py docs/tutorial

  # 只转换当前目录的 .md 文件（不递归）
  python convert_md_to_docx.py docs/tutorial --no-recursive

  # 覆盖已存在的 .docx 文件
  python convert_md_to_docx.py docs/tutorial --overwrite

  # 指定输出目录
  python convert_md_to_docx.py docs/tutorial --output output/docx

  # 传递额外的 pandoc 参数
  python convert_md_to_docx.py docs/tutorial --pandoc-args "--toc --toc-depth=2"

  # 只转换指定的文件
  python convert_md_to_docx.py docs/tutorial/1.员工入职欢迎信/template_welcome.md
        """
    )

    parser.add_argument(
        "path",
        help="要转换的目录或文件路径"
    )

    parser.add_argument(
        "-r", "--recursive",
        action="store_true",
        default=True,
        help="递归搜索子目录（默认: True）"
    )

    parser.add_argument(
        "--no-recursive",
        action="store_false",
        dest="recursive",
        help="不递归搜索子目录"
    )

    parser.add_argument(
        "-o", "--output",
        help="输出目录（默认: 与源文件同目录）"
    )

    parser.add_argument(
        "-f", "--overwrite",
        action="store_true",
        help="覆盖已存在的文件"
    )

    parser.add_argument(
        "--pandoc-args",
        help="传递给 pandoc 的额外参数（用引号包裹）",
        default=""
    )

    parser.add_argument(
        "-v", "--verbose",
        action="store_true",
        help="显示详细信息"
    )

    parser.add_argument(
        "--dry-run",
        action="store_true",
        help="仅显示将要转换的文件，不实际执行"
    )

    args = parser.parse_args()

    # 检查路径
    path = Path(args.path)

    if not path.exists():
        print(f"错误: 路径不存在: {args.path}")
        sys.exit(1)

    # 收集要转换的文件
    md_files = []

    if path.is_file():
        # 单个文件
        if path.suffix.lower() == ".md":
            md_files = [path]
        else:
            print(f"错误: 不是 Markdown 文件: {args.path}")
            sys.exit(1)
    elif path.is_dir():
        # 目录
        md_files = find_markdown_files(str(path), args.recursive)
    else:
        print(f"错误: 无效的路径: {args.path}")
        sys.exit(1)

    if not md_files:
        print("未找到任何 Markdown 文件")
        sys.exit(0)

    # 解析额外的 pandoc 参数
    pandoc_args = args.pandoc_args.split() if args.pandoc_args else []

    # 显示将要转换的文件
    print(f"找到 {len(md_files)} 个 Markdown 文件")

    if args.verbose or args.dry_run:
        print("\n文件列表:")
        for i, md_file in enumerate(md_files, 1):
            print(f"  {i}. {md_file}")
        print()

    if args.dry_run:
        print("dry-run 模式，不执行实际转换")
        sys.exit(0)

    # 执行转换
    success_count = 0
    fail_count = 0

    for md_file in md_files:
        if convert_md_to_docx(
            md_file,
            args.output,
            args.overwrite,
            pandoc_args
        ):
            success_count += 1
        else:
            fail_count += 1

    # 显示统计信息
    print(f"\n转换完成!")
    print(f"  成功: {success_count}")
    print(f"  失败: {fail_count}")
    print(f"  总计: {len(md_files)}")

    if fail_count > 0:
        sys.exit(1)


if __name__ == "__main__":
    main()
