import os
import base64
import subprocess
import tempfile
from datetime import datetime


class PDFGenerator:
    """PDF 生成器类（Pandoc 版）"""

    def __init__(self, main_font: str = "Noto Serif CJK SC"):
        """
        初始化 PDF 生成器

        Args:
            main_font: Pandoc / XeLaTeX 使用的中文字体名
        """
        self.main_font = main_font

    def generate_pdf_from_text(
        self,
        text_content: str,
        output_path: str = None,
        title: str = "维修报告",
        return_base64: bool = True
    ) -> dict:
        """
        将 Markdown 文本内容生成 PDF 文件

        Args:
            text_content: Markdown 文本内容
            output_path: PDF 输出路径（可选）
            title: PDF 标题
            return_base64: 是否返回 base64 编码内容
        """
        try:
            # 输出路径
            if output_path is None:
                timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
                output_path = f"temp_report_{timestamp}.pdf"

            # 生成临时 Markdown 文件
            with tempfile.NamedTemporaryFile(
                mode="w",
                suffix=".md",
                delete=False,
                encoding="utf-8"
            ) as md_file:
                md_path = md_file.name

                # 写入标题 + 内容
                if title:
                    md_file.write(f"# {title}\n\n")
                md_file.write(text_content.strip())

            # Pandoc 命令：使用自定义 LaTeX 模板解决排版问题
            cmd = [
                "pandoc",
                md_path,
                "--pdf-engine=xelatex",
                "-V", f"mainfont={self.main_font}",
                "-V", "geometry:margin=2cm",  # 增加页边距
                "-V", "fontsize=10pt",         # 字体大小
                "-V", "lineskip=1.5",          # 行距
                "--template=template.tex",     # 使用自定义模板
                "-o", output_path
            ]

            # 执行转换
            subprocess.run(
                cmd,
                check=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE
            )

            result = {
                "success": True,
                "file_path": output_path
            }

            # 返回 base64
            if return_base64:
                with open(output_path, "rb") as f:
                    result["base64_content"] = base64.b64encode(
                        f.read()
                    ).decode("utf-8")

            return result

        except subprocess.CalledProcessError as e:
            return {
                "success": False,
                "error": e.stderr.decode("utf-8")
            }
        except Exception as e:
            return {
                "success": False,
                "error": str(e)
            }
        finally:
            # 清理临时 md 文件
            if "md_path" in locals() and os.path.exists(md_path):
                os.remove(md_path)


# 创建自定义 LaTeX 模板文件 template.tex
def create_latex_template():
    """创建一个用于中文排版的 LaTeX 模板（Pandoc 正确版）"""
    template = r"""
\documentclass[10pt]{article}
\usepackage[UTF8]{ctex}
\usepackage{geometry}
\usepackage{graphicx}
\usepackage{amsmath}
\usepackage{array}
\usepackage{booktabs}
\usepackage{longtable}
\usepackage{setspace}
\usepackage{fancyhdr}
\usepackage{titlesec}
\usepackage{tabularx}
\usepackage{makecell}
\usepackage{adjustbox}
\usepackage{hyperref}
% 页面设置
\geometry{margin=2cm}
\setlength{\parskip}{1em}
\setlength{\parindent}{0em}

% 字体
\setCJKmainfont{Noto Serif CJK SC}

% 标题样式
\title{\Large \textbf{$title$}}
\author{}
\date{}

% 章节标题样式
\titleformat{\section}{\large\bfseries\raggedright}{\thesection}{1em}{}
\titleformat{\subsection}{\normalsize\bfseries\raggedright}{\thesubsection}{1em}{}


% ===== Pandoc compatibility =====
\usepackage{hyperref}
\providecommand{\tightlist}{%
  \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}


\begin{document}

\maketitle

$body$

\end{document}
"""
    with open("template.tex", "w", encoding="utf-8") as f:
        f.write(template)












# 生成报告函数不变，但调用前先创建模板
def generate_report_pdf(
    report_content: str,
    device_name: str = "未知设备",
    output_dir: str = None
) -> dict:
    """
    生成维修报告 PDF
    """
    # 先创建模板文件
    create_latex_template()

    generator = PDFGenerator()

    # 文件名规则不变
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    safe_device_name = device_name.replace(" ", "_").replace("/", "_")
    file_name = f"{safe_device_name}_维修报告_{timestamp}.pdf"

    if output_dir:
        os.makedirs(output_dir, exist_ok=True)
        output_path = os.path.join(output_dir, file_name)
    else:
        output_path = file_name

    result = generator.generate_pdf_from_text(
        text_content=report_content,
        output_path=output_path,
        title="设备维修报告",
        return_base64=True
    )

    if result.get("success"):
        result["file_name"] = file_name

    return result


# 测试代码
if __name__ == "__main__":
    test_md = """
三、根本原因判断

根据设备当前状态、维修方案参考和知识库检索结果，最可能的根本原因如下：

**根本原因**：缸盖密封环老化或失效  
**次级原因**：启动阀卡滞或内部泄漏

---

四、原因分析说明

1. **缸盖密封环老化或失效**
   - 缸盖密封环是气缸密封的关键部件，其老化或损坏会导致气缸压缩气体泄漏，压缩压力下降。
   - 启动时，压缩压力不足会导致点火困难，主机启动延迟或失败。
   - 此类问题在长期运行或未定期保养的设备中较为常见。

2. **启动阀卡滞或内部泄漏**
   - 启动阀的功能是控制启动气进入气缸，若其卡滞或内部泄漏，将导致启动气供应不足或不及时，影响启动成功率。
   - 内部泄漏还会造成启动气浪费，进一步降低启动成功率。
   - 启动阀若未定期维护，容易因灰尘、杂质或润滑不良而卡滞。

3. **气缸套磨损**
   - 气缸套磨损会导致气缸密封性下降，压缩气体泄漏，压缩压力不足。
   - 该问题通常发生在长期运行、润滑不良或未及时更换气缸套的设备中。

4. **活塞环磨损或断裂**
   - 活塞环磨损或断裂会导致气缸密封性下降，压缩气体泄漏，从而影响压缩压力。
   - 该问题通常与长期运行、润滑不良或材料疲劳有关。

5. **调速系统响应异常**
   - 调速系统异常可能导致主机启动时转速控制不稳，但其对压缩压力的影响相对较小，通常不是导致压缩压力不足的主要原因。

---

五、预防建议

1. 定期更换缸盖密封环
   - 根据设备运行时间和使用情况，制定合理的密封环更换计划，避免因老化导致密封性能下降。
   - 建议每运行 5000 小时进行一次检查，必要时更换。

2. 加强启动阀维护
   - 定期清理启动阀内部积碳和杂质，保持润滑良好。
   - 每 1000 小时进行一次功能测试。

3. 监控气缸套和活塞环状态
   - 通过内窥镜或压力测试定期检测气缸套与活塞环磨损情况。
   - 发现异常及时更换。

4. 优化润滑系统
   - 使用符合标准的润滑油，确保润滑充分。
   - 定期更换滤芯，防止杂质进入关键部件。

5. 定期校准调速系统
   - 每季度进行一次调速系统校准，确保响应灵敏。
   - 记录历史数据，建立趋势分析模型。
"""

    result = generate_report_pdf(
        test_md,
        device_name="压缩机设备"
    )

    if result["success"]:
        print(f"✓ PDF 生成成功：{result['file_name']}")
        print(f"✓ 文件路径：{result['file_path']}")
        print(f"✓ Base64 长度：{len(result['base64_content'])}")
    else:
        print(f"✗ PDF 生成失败：{result['error']}")
