from pathlib import Path

from docx import Document
from docx.enum.table import WD_CELL_VERTICAL_ALIGNMENT
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
from docx.shared import Pt


ROOT = Path(__file__).resolve().parent
STARTER = ROOT / "working-copy.docx"
OUTPUT = ROOT / "manual.docx"


def set_font(run, size=11, bold=False):
    run.font.name = "Noto Sans CJK SC"
    run._element.rPr.rFonts.set(qn("w:eastAsia"), "Noto Sans CJK SC")
    run.font.size = Pt(size)
    run.bold = bold


def set_cell_fill(cell, color):
    tc_pr = cell._tc.get_or_add_tcPr()
    shd = OxmlElement("w:shd")
    shd.set(qn("w:fill"), color)
    tc_pr.append(shd)


def set_table_borders(table):
    tbl_pr = table._tbl.tblPr
    borders = OxmlElement("w:tblBorders")
    for edge in ("top", "left", "bottom", "right", "insideH", "insideV"):
        node = OxmlElement(f"w:{edge}")
        node.set(qn("w:val"), "single")
        node.set(qn("w:sz"), "4")
        node.set(qn("w:color"), "D9D9D9")
        borders.append(node)
    tbl_pr.append(borders)


def add_paragraph(doc, text, size=11, bold=False, after=6):
    paragraph = doc.add_paragraph()
    paragraph.paragraph_format.space_after = Pt(after)
    paragraph.paragraph_format.line_spacing = 1.35
    set_font(paragraph.add_run(text), size=size, bold=bold)
    return paragraph


doc = Document(STARTER)
body = doc._element.body
for paragraph in list(doc.paragraphs):
    if not paragraph.text.strip():
        body.remove(paragraph._element)

title = doc.add_paragraph()
title.alignment = WD_ALIGN_PARAGRAPH.CENTER
title.paragraph_format.space_after = Pt(14)
set_font(title.add_run("供餐对象维护操作说明"), size=20, bold=True)

add_paragraph(doc, "本说明用于维护学校膳食营养模块的供餐对象。新增时系统自动生成内部编码，用户只需维护业务信息。", after=12)

add_paragraph(doc, "入口与权限", size=15, bold=True, after=6)
add_paragraph(doc, "入口：膳食营养 → 基础设置 → 供餐对象。适用于具有供餐对象新增、编辑或启停权限的营养负责人和系统管理员。")

add_paragraph(doc, "新增步骤", size=15, bold=True, after=6)
for index, text in enumerate([
    "点击“新增供餐对象”并选择所属学校。",
    "填写对象名称并选择标准年龄段。",
    "设置排序后保存。",
    "保存成功后，系统自动生成只读系统编码。",
], start=1):
    add_paragraph(doc, f"{index}. {text}", after=3)

add_paragraph(doc, "字段说明", size=15, bold=True, after=6)
rows = [
    ("所属学校", "必填", "决定数据权限范围，创建后不可迁移"),
    ("对象名称", "必填", "用户可识别的业务名称，同一学校内不能重复"),
    ("标准年龄段", "必填", "用于匹配当前营养参考规则"),
    ("排序", "选填", "数值越小越靠前，范围为 0 至 9999"),
    ("系统编码", "无需填写", "系统自动生成并保持不变，只读展示"),
]
table = doc.add_table(rows=1, cols=3)
set_table_borders(table)
headers = ["字段", "填写要求", "说明"]
for idx, text in enumerate(headers):
    cell = table.rows[0].cells[idx]
    set_cell_fill(cell, "D9EAF7")
    cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
    paragraph = cell.paragraphs[0]
    paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
    set_font(paragraph.add_run(text), size=10, bold=True)
for field, required, description in rows:
    cells = table.add_row().cells
    for idx, text in enumerate((field, required, description)):
        cells[idx].vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
        paragraph = cells[idx].paragraphs[0]
        paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER if idx < 2 else WD_ALIGN_PARAGRAPH.LEFT
        set_font(paragraph.add_run(text), size=10)

add_paragraph(doc, "编辑与历史规则", size=15, bold=True, after=6)
add_paragraph(doc, "可修改对象名称、标准年龄段和排序；系统编码创建后保持不变。停用或修改主档不会追改既有食谱及已发布版本保存的对象快照。")

add_paragraph(doc, "验证信息", size=15, bold=True, after=6)
add_paragraph(doc, "本地 Docker 验证：学校膳食营养模块 111 tests / 955 assertions；PC 生产构建通过。验证日期：2026-09-21。", after=0)

doc.save(OUTPUT)
print(OUTPUT)
