#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
报告 .docx 生成器
根据《报告通用铁律 v1.0》格式标准生成公文格式 Word 文档

用法:
  python generate_report_docx.py <报告标题> <输出路径.docx> << 'CONTENT_EOF'
  (markdown 格式内容)
  CONTENT_EOF

或:
  python generate_report_docx.py <报告标题> <输出路径.docx> < content.md
"""
import sys
import re
import os
from docx import Document
from docx.shared import Pt, Emu, Cm, Mm
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml.ns import qn

def setup_page(doc):
    """设置页面 - A4, 标准公文页边距"""
    section = doc.sections[0]
    section.page_width = Mm(210)
    section.page_height = Mm(297)
    section.top_margin = Mm(37)
    section.bottom_margin = Mm(35)
    section.left_margin = Mm(28)
    section.right_margin = Mm(26)

def set_font(run, font_name, size_pt, bold=False):
    """设置字体"""
    run.font.size = Pt(size_pt)
    run.font.name = font_name
    run.bold = bold
    # 设置东亚字体
    r = run._element
    rPr = r.find(qn('w:rPr'))
    if rPr is None:
        rPr = r.makeelement(qn('w:rPr'), {})
        r.insert(0, rPr)
    rFonts = rPr.find(qn('w:rFonts'))
    if rFonts is None:
        rFonts = rPr.makeelement(qn('w:rFonts'), {})
        rPr.insert(0, rFonts)
    rFonts.set(qn('w:eastAsia'), font_name)
    rFonts.set(qn('w:ascii'), font_name)
    rFonts.set(qn('w:hAnsi'), font_name)

def set_paragraph_format(para, first_line_indent=True, alignment=None, line_spacing_pt=28):
    """设置段落格式"""
    pf = para.paragraph_format
    pf.left_indent = None
    if first_line_indent:
        pf.first_line_indent = Emu(406400)  # 2字符缩进
    else:
        pf.first_line_indent = None
    pf.line_spacing = Pt(line_spacing_pt)
    if alignment:
        para.alignment = alignment

def add_title(doc, text):
    """添加主标题 - 2号小标宋居中"""
    para = doc.add_paragraph()
    set_paragraph_format(para, first_line_indent=False, alignment=WD_ALIGN_PARAGRAPH.CENTER)
    run = para.add_run(text)
    set_font(run, '小标宋', 22, bold=False)
    # 设置东亚字体
    rPr = run._element.find(qn('w:rPr'))
    if rPr is not None:
        rFonts = rPr.find(qn('w:rFonts'))
        if rFonts is not None:
            rFonts.set(qn('w:eastAsia'), '小标宋')

def add_chapter_heading(doc, text):
    """添加章标题 - 3号黑体左对齐加粗"""
    para = doc.add_paragraph()
    set_paragraph_format(para, first_line_indent=False, alignment=WD_ALIGN_PARAGRAPH.LEFT)
    run = para.add_run(text)
    set_font(run, '黑体', 16, bold=True)

def add_section_heading(doc, text):
    """添加节标题(一、二、) - 3号黑体左对齐加粗"""
    para = doc.add_paragraph()
    set_paragraph_format(para, first_line_indent=False, alignment=WD_ALIGN_PARAGRAPH.LEFT)
    run = para.add_run(text)
    set_font(run, '黑体', 16, bold=True)

def add_subsection_heading(doc, text):
    """添加小节标题(（一）（二）) - 3号楷体左对齐"""
    para = doc.add_paragraph()
    set_paragraph_format(para, first_line_indent=False, alignment=WD_ALIGN_PARAGRAPH.LEFT)
    run = para.add_run(text)
    set_font(run, '楷体', 16, bold=False)

def add_body_paragraph(doc, text):
    """添加正文段落 - 3号仿宋首行缩进2字符"""
    para = doc.add_paragraph()
    set_paragraph_format(para, first_line_indent=True, alignment=WD_ALIGN_PARAGRAPH.JUSTIFY)
    run = para.add_run(text)
    set_font(run, '仿宋_GB2312', 16, bold=False)

def add_reference_paragraph(doc, text):
    """添加参考文献段落 - 小四号仿宋悬挂缩进"""
    para = doc.add_paragraph()
    pf = para.paragraph_format
    pf.left_indent = Emu(304800)
    pf.first_line_indent = Emu(-304800)
    pf.line_spacing = Pt(28)
    para.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
    run = para.add_run(text)
    set_font(run, '仿宋', 12, bold=False)

def parse_and_generate(doc, content):
    """解析 markdown 内容并生成格式化的 docx"""
    lines = content.strip().split('\n')
    i = 0
    in_references = False
    skip_title = False
    
    for line in lines:
        line = line.rstrip()
        
        # 跳过空行
        if not line.strip():
            continue
            
        # 去掉 markdown 标记
        text = line.strip()
        
        # 跳过 markdown 标题标记（# 开头），但第一个 # 标题作为主标题
        if text.startswith('# ') and not skip_title:
            title_text = text[2:].strip()
            add_title(doc, title_text)
            skip_title = True
            continue
        elif text.startswith('## '):
            # ## 作为章标题
            chapter_text = text[3:].strip()
            add_chapter_heading(doc, chapter_text)
            continue
        elif text.startswith('### '):
            # ### 作为节标题
            section_text = text[4:].strip()
            add_section_heading(doc, section_text)
            continue
        elif text.startswith('#### '):
            subsection_text = text[5:].strip()
            add_subsection_heading(doc, subsection_text)
            continue
            
        # 参考文献/附录标记
        if re.match(r'^(参考文献|附录)', text):
            in_references = True
            add_chapter_heading(doc, text)
            continue
            
        # 参考文献条目（以 ① ② ③ 或数字开头）
        if in_references and re.match(r'^[①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳\d]+\s', text):
            add_reference_paragraph(doc, text)
            continue
            
        # 普通正文段落 - 去除 markdown 残留
        # 去除行首项目符号
        text = re.sub(r'^[·•・\-*]\s*', '', text)
        # 去除 **加粗** 标记
        text = re.sub(r'\*\*([^*]+)\*\*', r'\1', text)
        # 去除 --- 分隔线
        if re.match(r'^[-=]{3,}$', text):
            continue
        
        # 判断是否是"第X章"格式
        if re.match(r'^第[一二三四五六七八九十]+章', text):
            add_chapter_heading(doc, text)
            continue
        # 判断是否是"一、二、"格式
        if re.match(r'^[一二三四五六七八九十]+[、．\.]', text):
            add_section_heading(doc, text)
            continue
        # 判断是否是"（一）（二）"格式
        if re.match(r'^[（(][一二三四五六七八九十]+[）)]', text):
            add_subsection_heading(doc, text)
            continue
            
        # 默认作为正文
        add_body_paragraph(doc, text)

def main():
    if len(sys.argv) < 3:
        print("用法: python generate_report_docx.py <报告标题> <输出路径.docx> < content.md")
        print("  或: python generate_report_docx.py <报告标题> <输出路径.docx> << 'EOF'")
        sys.exit(1)
    
    title = sys.argv[1]
    output_path = sys.argv[2]
    
    # 读取 stdin 内容
    content = sys.stdin.read()
    
    doc = Document()
    setup_page(doc)
    
    # 如果内容中没有 # 标题，手动添加
    if not content.strip().startswith('# '):
        add_title(doc, title)
    else:
        # 使用内容中的标题
        pass
    
    parse_and_generate(doc, content)
    
    doc.save(output_path)
    print(f"✅ 报告已生成: {output_path}")

if __name__ == '__main__':
    main()
