#!/usr/bin/env python3
"""Generate an A4 Chinese official-style DOCX for procurement project reports.

Usage:
  python make_procurement_report_docx.py input.md output.docx
"""
from __future__ import annotations
import re
import sys
from pathlib import Path
from docx import Document
from docx.enum.section import WD_SECTION
from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_LINE_SPACING
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
from docx.shared import Mm, Pt

CH_NUM = "一二三四五六七八九十"


def set_run_font(run, east_asia: str, size_pt: int | float, bold: bool = False):
    run.font.name = east_asia
    run._element.rPr.rFonts.set(qn('w:eastAsia'), east_asia)
    run._element.rPr.rFonts.set(qn('w:ascii'), 'Times New Roman')
    run._element.rPr.rFonts.set(qn('w:hAnsi'), 'Times New Roman')
    run.font.size = Pt(size_pt)
    run.bold = bold


def set_para(paragraph, *, first_indent=True, align=None, line_pt=28):
    fmt = paragraph.paragraph_format
    fmt.line_spacing_rule = WD_LINE_SPACING.EXACTLY
    fmt.line_spacing = Pt(line_pt)
    fmt.space_before = Pt(0)
    fmt.space_after = Pt(0)
    if first_indent:
        fmt.first_line_indent = Pt(32)  # approx 2 chars at 16pt
    else:
        fmt.first_line_indent = Pt(0)
    if align is not None:
        paragraph.alignment = align


def add_page_number(section):
    footer = section.footer
    p = footer.paragraphs[0]
    p.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = p.add_run()
    fld = OxmlElement('w:fldSimple')
    fld.set(qn('w:instr'), 'PAGE')
    run._r.append(fld)


def classify(line: str):
    s = line.strip()
    if not s:
        return 'blank'
    if s == '参考文献':
        return 'refs_title'
    if re.match(rf'^[{CH_NUM}]、', s):
        return 'chapter'
    if re.match(r'^（[一二三四五六七八九十]+）', s):
        return 'section'
    if re.match(r'^\d+[\.、]\s*', s) or s.startswith('['):
        return 'reference'
    return 'body'


def add_paragraph(doc, text, kind):
    p = doc.add_paragraph()
    if kind == 'title':
        set_para(p, first_indent=False, align=WD_ALIGN_PARAGRAPH.CENTER, line_pt=28)
        r = p.add_run(text)
        set_run_font(r, 'SimSun', 22, bold=True)
    elif kind == 'chapter':
        set_para(p, first_indent=False, align=WD_ALIGN_PARAGRAPH.LEFT, line_pt=28)
        r = p.add_run(text)
        set_run_font(r, 'SimHei', 16, bold=True)
    elif kind == 'section':
        set_para(p, first_indent=True, align=WD_ALIGN_PARAGRAPH.LEFT, line_pt=28)
        r = p.add_run(text)
        set_run_font(r, 'KaiTi', 16, bold=False)
    elif kind == 'refs_title':
        set_para(p, first_indent=False, align=WD_ALIGN_PARAGRAPH.LEFT, line_pt=28)
        r = p.add_run(text)
        set_run_font(r, 'SimHei', 16, bold=True)
    elif kind == 'reference':
        set_para(p, first_indent=False, align=WD_ALIGN_PARAGRAPH.LEFT, line_pt=24)
        r = p.add_run(text)
        set_run_font(r, 'FangSong', 14, bold=False)
    else:
        set_para(p, first_indent=True, align=WD_ALIGN_PARAGRAPH.LEFT, line_pt=28)
        r = p.add_run(text)
        set_run_font(r, 'FangSong', 16, bold=False)


def main():
    if len(sys.argv) != 3:
        print(__doc__)
        sys.exit(2)
    src, dst = Path(sys.argv[1]), Path(sys.argv[2])
    text = src.read_text(encoding='utf-8')
    lines = [re.sub(r'^#+\s*', '', x).rstrip() for x in text.splitlines()]
    lines = [x for x in lines if x.strip()]
    if not lines:
        raise SystemExit('input is empty')

    doc = Document()
    sec = doc.sections[0]
    sec.page_width = Mm(210)
    sec.page_height = Mm(297)
    sec.top_margin = Mm(37)
    sec.bottom_margin = Mm(35)
    sec.left_margin = Mm(28)
    sec.right_margin = Mm(26)
    add_page_number(sec)

    add_paragraph(doc, lines[0].strip(), 'title')
    for line in lines[1:]:
        kind = classify(line)
        if kind == 'blank':
            continue
        add_paragraph(doc, line.strip(), kind)

    doc.save(dst)
    print(dst)

if __name__ == '__main__':
    main()
