#!/usr/bin/env python3
"""Build a journal-oriented Word manuscript and cover letter from verified results."""

from __future__ import annotations

import argparse
import json
import re
from pathlib import Path

from docx import Document
from docx.enum.section import WD_SECTION
from docx.enum.style import WD_STYLE_TYPE
from docx.enum.table import WD_CELL_VERTICAL_ALIGNMENT, WD_TABLE_ALIGNMENT
from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_BREAK, WD_LINE_SPACING
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
from docx.shared import Cm, Inches, Pt, RGBColor


NAVY = "1F4E79"
BLUE = "DCE8F3"
PALE = "F5F8FB"
GOLD = "D5963B"
INK = "1F2937"
GRAY = "64748B"
LINE = "CBD5E1"
YELLOW = "FFF2CC"

TITLE = (
    "Trends and Population Contributors to Cesarean Delivery in the United States, "
    "2016–2024: A Repeated Cross-Sectional Analysis Using a Modified Robson Classification"
)
SHORT_TITLE = "U.S. cesarean delivery by modified Robson group"

GROUP_DEFINITIONS = {
    "1": "Nulliparous, term, singleton, cephalic, spontaneous labor",
    "2": "Nulliparous, term, singleton, cephalic, induced labor or prelabor cesarean",
    "3": "Multiparous without previous cesarean, term, singleton, cephalic, spontaneous labor",
    "4": "Multiparous without previous cesarean, term, singleton, cephalic, induced labor or prelabor cesarean",
    "5": "Previous cesarean, term, singleton, cephalic",
    "6": "Nulliparous singleton breech",
    "7": "Multiparous singleton breech",
    "8": "Multiple pregnancy",
    "9": "Singleton with other/non-cephalic, non-breech presentation",
    "10": "Singleton cephalic, preterm",
}


def set_cell_shading(cell, fill: str) -> None:
    tc_pr = cell._tc.get_or_add_tcPr()
    shd = tc_pr.find(qn("w:shd"))
    if shd is None:
        shd = OxmlElement("w:shd")
        tc_pr.append(shd)
    shd.set(qn("w:fill"), fill)


def set_cell_margins(cell, top=80, start=90, bottom=80, end=90) -> None:
    tc = cell._tc
    tc_pr = tc.get_or_add_tcPr()
    tc_mar = tc_pr.first_child_found_in("w:tcMar")
    if tc_mar is None:
        tc_mar = OxmlElement("w:tcMar")
        tc_pr.append(tc_mar)
    for margin, value in (("top", top), ("start", start), ("bottom", bottom), ("end", end)):
        node = tc_mar.find(qn(f"w:{margin}"))
        if node is None:
            node = OxmlElement(f"w:{margin}")
            tc_mar.append(node)
        node.set(qn("w:w"), str(value))
        node.set(qn("w:type"), "dxa")


def set_table_borders(table) -> None:
    tbl_pr = table._tbl.tblPr
    borders = tbl_pr.first_child_found_in("w:tblBorders")
    if borders is None:
        borders = OxmlElement("w:tblBorders")
        tbl_pr.append(borders)
    for edge in ("top", "left", "bottom", "right", "insideH"):
        tag = borders.find(qn(f"w:{edge}"))
        if tag is None:
            tag = OxmlElement(f"w:{edge}")
            borders.append(tag)
        tag.set(qn("w:val"), "single")
        tag.set(qn("w:sz"), "4")
        tag.set(qn("w:color"), LINE)
    inside_v = borders.find(qn("w:insideV"))
    if inside_v is None:
        inside_v = OxmlElement("w:insideV")
        borders.append(inside_v)
    inside_v.set(qn("w:val"), "nil")


def repeat_table_header(row) -> None:
    tr_pr = row._tr.get_or_add_trPr()
    tbl_header = OxmlElement("w:tblHeader")
    tbl_header.set(qn("w:val"), "true")
    tr_pr.append(tbl_header)


def keep_row_together(row) -> None:
    tr_pr = row._tr.get_or_add_trPr()
    cant_split = OxmlElement("w:cantSplit")
    tr_pr.append(cant_split)


def add_field(paragraph, instruction: str) -> None:
    run = paragraph.add_run()
    fld_char_begin = OxmlElement("w:fldChar")
    fld_char_begin.set(qn("w:fldCharType"), "begin")
    instr_text = OxmlElement("w:instrText")
    instr_text.set(qn("xml:space"), "preserve")
    instr_text.text = instruction
    fld_char_separate = OxmlElement("w:fldChar")
    fld_char_separate.set(qn("w:fldCharType"), "separate")
    text = OxmlElement("w:t")
    text.text = "1"
    fld_char_end = OxmlElement("w:fldChar")
    fld_char_end.set(qn("w:fldCharType"), "end")
    run._r.extend([fld_char_begin, instr_text, fld_char_separate, text, fld_char_end])


def set_line_numbering(section) -> None:
    sect_pr = section._sectPr
    current = sect_pr.find(qn("w:lnNumType"))
    if current is not None:
        sect_pr.remove(current)
    line_numbers = OxmlElement("w:lnNumType")
    line_numbers.set(qn("w:countBy"), "5")
    line_numbers.set(qn("w:distance"), "360")
    line_numbers.set(qn("w:restart"), "continuous")
    sect_pr.append(line_numbers)


def set_update_fields(doc: Document) -> None:
    settings = doc.settings._element
    update = settings.find(qn("w:updateFields"))
    if update is None:
        update = OxmlElement("w:updateFields")
        settings.append(update)
    update.set(qn("w:val"), "true")


def add_hyperlink(paragraph, text: str, url: str) -> None:
    part = paragraph.part
    relationship_id = part.relate_to(
        url,
        "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
        is_external=True,
    )
    hyperlink = OxmlElement("w:hyperlink")
    hyperlink.set(qn("r:id"), relationship_id)
    run = OxmlElement("w:r")
    run_properties = OxmlElement("w:rPr")
    color = OxmlElement("w:color")
    color.set(qn("w:val"), NAVY)
    underline = OxmlElement("w:u")
    underline.set(qn("w:val"), "single")
    run_properties.extend([color, underline])
    run.append(run_properties)
    text_node = OxmlElement("w:t")
    text_node.text = text
    run.append(text_node)
    hyperlink.append(run)
    paragraph._p.append(hyperlink)


def configure_document(doc: Document, *, short_title: str) -> None:
    section = doc.sections[0]
    section.top_margin = Cm(2.2)
    section.bottom_margin = Cm(2.2)
    section.left_margin = Cm(2.5)
    section.right_margin = Cm(2.2)
    section.header_distance = Cm(0.9)
    section.footer_distance = Cm(0.9)
    set_line_numbering(section)
    set_update_fields(doc)

    styles = doc.styles
    normal = styles["Normal"]
    normal.font.name = "Times New Roman"
    normal.font.size = Pt(11)
    normal.font.color.rgb = RGBColor.from_string(INK)
    normal._element.rPr.rFonts.set(qn("w:eastAsia"), "Times New Roman")
    normal.paragraph_format.line_spacing_rule = WD_LINE_SPACING.DOUBLE
    normal.paragraph_format.space_after = Pt(0)

    title_style = styles["Title"]
    title_style.font.name = "Arial"
    title_style.font.size = Pt(20)
    title_style.font.bold = True
    title_style.font.color.rgb = RGBColor.from_string(NAVY)
    title_style._element.rPr.rFonts.set(qn("w:eastAsia"), "Arial")
    title_style.paragraph_format.space_after = Pt(12)

    for level, size in [(1, 15), (2, 12), (3, 11)]:
        style = styles[f"Heading {level}"]
        style.font.name = "Arial"
        style.font.size = Pt(size)
        style.font.bold = True
        style.font.color.rgb = RGBColor.from_string(NAVY)
        style._element.rPr.rFonts.set(qn("w:eastAsia"), "Arial")
        style.paragraph_format.space_before = Pt(10 if level == 1 else 6)
        style.paragraph_format.space_after = Pt(4)
        style.paragraph_format.keep_with_next = True

    if "Figure Caption" not in styles:
        caption_style = styles.add_style("Figure Caption", WD_STYLE_TYPE.PARAGRAPH)
    else:
        caption_style = styles["Figure Caption"]
    caption_style.font.name = "Arial"
    caption_style.font.size = Pt(9)
    caption_style.font.color.rgb = RGBColor.from_string(INK)
    caption_style.paragraph_format.line_spacing_rule = WD_LINE_SPACING.SINGLE
    caption_style.paragraph_format.space_before = Pt(3)
    caption_style.paragraph_format.space_after = Pt(8)

    header = section.header
    header_paragraph = header.paragraphs[0]
    header_paragraph.alignment = WD_ALIGN_PARAGRAPH.LEFT
    run = header_paragraph.add_run(short_title)
    run.font.name = "Arial"
    run.font.size = Pt(8.5)
    run.font.color.rgb = RGBColor.from_string(GRAY)
    header_paragraph.add_run("\t")
    right = header_paragraph.add_run("RESEARCH ARTICLE")
    right.font.name = "Arial"
    right.font.size = Pt(8.5)
    right.font.bold = True
    right.font.color.rgb = RGBColor.from_string(NAVY)
    tabs = header_paragraph.paragraph_format.tab_stops
    tabs.add_tab_stop(Inches(6.2))

    footer = section.footer
    paragraph = footer.paragraphs[0]
    paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = paragraph.add_run("Page ")
    run.font.name = "Arial"
    run.font.size = Pt(8.5)
    run.font.color.rgb = RGBColor.from_string(GRAY)
    add_field(paragraph, "PAGE")


def add_body_paragraph(doc: Document, text: str, *, bold_prefix: str | None = None):
    paragraph = doc.add_paragraph()
    if bold_prefix and text.startswith(bold_prefix):
        run = paragraph.add_run(bold_prefix)
        run.bold = True
        paragraph.add_run(text[len(bold_prefix) :])
    else:
        paragraph.add_run(text)
    return paragraph


def add_confirmation_paragraph(doc: Document, heading: str, text: str) -> None:
    paragraph = doc.add_paragraph()
    lead = paragraph.add_run(heading)
    lead.bold = True
    marker = paragraph.add_run("[AUTHOR TO CONFIRM] ")
    marker.bold = True
    marker.font.highlight_color = 7
    paragraph.add_run(text)


def add_section_heading(doc: Document, text: str, level: int = 1):
    return doc.add_heading(text, level=level)


def add_title_band(doc: Document, label: str) -> None:
    table = doc.add_table(rows=1, cols=2)
    table.alignment = WD_TABLE_ALIGNMENT.LEFT
    table.autofit = False
    table.columns[0].width = Cm(4.4)
    table.columns[1].width = Cm(11.8)
    table.cell(0, 0).text = label
    table.cell(0, 1).text = "BMC Pregnancy and Childbirth candidate"
    for idx, cell in enumerate(table.rows[0].cells):
        set_cell_shading(cell, NAVY if idx == 0 else BLUE)
        set_cell_margins(cell, 70, 110, 70, 110)
        paragraph = cell.paragraphs[0]
        paragraph.paragraph_format.line_spacing_rule = WD_LINE_SPACING.SINGLE
        run = paragraph.runs[0]
        run.font.name = "Arial"
        run.font.size = Pt(9)
        run.bold = True
        run.font.color.rgb = RGBColor.from_string("FFFFFF" if idx == 0 else NAVY)
    doc.add_paragraph().paragraph_format.space_after = Pt(0)


def add_table(
    doc: Document,
    *,
    title: str,
    headers: list[str],
    rows: list[list[str]],
    widths_cm: list[float],
    notes: list[str] | None = None,
) -> None:
    caption = doc.add_paragraph(style="Figure Caption")
    caption.paragraph_format.keep_with_next = True
    run = caption.add_run(title)
    run.bold = True

    table = doc.add_table(rows=1, cols=len(headers))
    table.alignment = WD_TABLE_ALIGNMENT.CENTER
    table.autofit = False
    set_table_borders(table)
    for index, (header, width) in enumerate(zip(headers, widths_cm)):
        cell = table.cell(0, index)
        cell.width = Cm(width)
        cell.text = header
        set_cell_shading(cell, NAVY)
        set_cell_margins(cell)
        cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
        paragraph = cell.paragraphs[0]
        paragraph.alignment = WD_ALIGN_PARAGRAPH.LEFT
        paragraph.paragraph_format.line_spacing_rule = WD_LINE_SPACING.SINGLE
        for run in paragraph.runs:
            run.font.name = "Arial"
            run.font.size = Pt(8)
            run.bold = True
            run.font.color.rgb = RGBColor(255, 255, 255)
    repeat_table_header(table.rows[0])

    for row_index, values in enumerate(rows):
        cells = table.add_row().cells
        keep_row_together(table.rows[-1])
        for column_index, (value, width) in enumerate(zip(values, widths_cm)):
            cell = cells[column_index]
            cell.width = Cm(width)
            cell.text = value
            set_cell_shading(cell, PALE if row_index % 2 else "FFFFFF")
            set_cell_margins(cell)
            cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.TOP
            paragraph = cell.paragraphs[0]
            paragraph.paragraph_format.line_spacing_rule = WD_LINE_SPACING.SINGLE
            paragraph.paragraph_format.space_after = Pt(0)
            for run in paragraph.runs:
                run.font.name = "Arial"
                run.font.size = Pt(7.8)
                run.font.color.rgb = RGBColor.from_string(INK)

    if notes:
        for note in notes:
            paragraph = doc.add_paragraph(style="Figure Caption")
            paragraph.paragraph_format.space_after = Pt(1)
            paragraph.add_run(note)


def add_figure(
    doc: Document,
    *,
    image_path: Path,
    caption_title: str,
    legend: str,
    width_inches: float = 6.35,
) -> None:
    paragraph = doc.add_paragraph()
    paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
    paragraph.paragraph_format.keep_with_next = True
    paragraph.add_run().add_picture(str(image_path), width=Inches(width_inches))
    caption = doc.add_paragraph(style="Figure Caption")
    caption_run = caption.add_run(caption_title)
    caption_run.bold = True
    caption.add_run(f" {legend}")


def main_text_word_count(texts: list[str]) -> int:
    return sum(len(re.findall(r"\b[\w–-]+\b", text)) for text in texts)


def build_manuscript(results: dict, figure_dir: Path, output_path: Path) -> None:
    doc = Document()
    configure_document(doc, short_title=SHORT_TITLE)
    doc.core_properties.title = TITLE
    doc.core_properties.subject = "Repeated cross-sectional NVSS natality analysis"
    doc.core_properties.author = "Chunxiao Zhou; Jixue Xiao"

    add_title_band(doc, "RESEARCH ARTICLE")
    title = doc.add_paragraph(style="Title")
    title.add_run(TITLE)

    authors = doc.add_paragraph()
    authors.paragraph_format.line_spacing_rule = WD_LINE_SPACING.SINGLE
    authors.alignment = WD_ALIGN_PARAGRAPH.LEFT
    run = authors.add_run("Chunxiao Zhou")
    run.bold = True
    authors.add_run(" and ")
    run = authors.add_run("Jixue Xiao")
    run.bold = True
    authors.add_run("*")

    affiliation = doc.add_paragraph()
    affiliation.paragraph_format.line_spacing_rule = WD_LINE_SPACING.SINGLE
    affiliation.add_run("Affiliation: ").bold = True
    affiliation.add_run("Liaocheng Second People’s Hospital, Liaocheng, Shandong, China")

    corresponding = doc.add_paragraph()
    corresponding.paragraph_format.line_spacing_rule = WD_LINE_SPACING.SINGLE
    corresponding.add_run("*Corresponding author: ").bold = True
    corresponding.add_run("Jixue Xiao; ")
    add_hyperlink(corresponding, "17588269328@163.com", "mailto:17588269328@163.com")

    article_info = doc.add_paragraph()
    article_info.paragraph_format.line_spacing_rule = WD_LINE_SPACING.SINGLE
    article_info.add_run("Article type: ").bold = True
    article_info.add_run("Research article | ")
    article_info.add_run("Reporting guidance: ").bold = True
    article_info.add_run("STROBE and RECORD")

    abstract_texts = [
        (
            "Background: The United States cesarean delivery rate has increased from its recent low, "
            "but the aggregate rate does not show which obstetric populations account for the change. "
            "We quantified national trends and the contributions of modified Robson groups from 2016 through 2024."
        ),
        (
            "Methods: We conducted a repeated cross-sectional analysis of National Vital Statistics "
            "System natality public-use files. U.S.-resident hospital live births with known delivery "
            "method and sufficient variables were assigned to a modified Robson group. We estimated "
            "group size, group-specific cesarean rate, and relative contribution. Log-linear trends "
            "were modeled with quasi-Poisson regression, and a symmetric Kitagawa decomposition "
            "separated population-share from within-group rate effects."
        ),
        (
            "Results: Among 32,647,302 classified births, annual classification completeness was "
            "99.00%–99.58%. The cesarean rate increased from 32.29% in 2016 to 33.12% in 2024 "
            "(+0.84 percentage points; annual percent change, 0.358%; 95% CI, 0.221%–0.494%). "
            "In 2024, groups 5, 2, and 10 accounted for 32.21%, 21.60%, and 10.09% of cesareans. "
            "Group 2 contributed +1.15 percentage points to the overall change because its population "
            "share increased from 13.49% to 18.34%, despite a decline in its cesarean rate from 44.54% "
            "to 39.02%. This expansion was concentrated in induced nulliparous term births (group 2a). "
            "Group 10 contributed +0.64 percentage points as both its population share and cesarean rate "
            "increased. Group 5 remained the largest contributor but offset the national increase by "
            "0.48 percentage points. Excluding modified group 9 yielded a +1.04-percentage-point increase."
        ),
        (
            "Conclusions: The modest national increase was not an across-the-board rise in "
            "group-specific cesarean use. It mainly reflected a larger induced nulliparous term "
            "population and an increasing contribution from preterm singleton cephalic births. "
            "National surveillance and quality improvement should distinguish changes in population "
            "composition from changes in delivery practice."
        ),
    ]
    abstract_words = main_text_word_count(abstract_texts)
    if abstract_words > 350:
        raise RuntimeError(f"Abstract exceeds 350 words: {abstract_words}")

    add_section_heading(doc, "Abstract", 1)
    for text in abstract_texts:
        prefix = text.split(":", 1)[0] + ":"
        add_body_paragraph(doc, text, bold_prefix=prefix)
    keywords = doc.add_paragraph()
    keywords.add_run("Keywords: ").bold = True
    keywords.add_run(
        "cesarean delivery; Robson classification; National Vital Statistics System; "
        "natality; trend; decomposition; United States"
    )

    main_texts: list[str] = []

    add_section_heading(doc, "Background", 1)
    background = [
        (
            "Cesarean delivery is a lifesaving intervention when medically indicated, but it also "
            "carries immediate and future maternal and neonatal consequences and may influence risk "
            "in subsequent pregnancies [3,12]. Cesarean use has increased worldwide, with substantial "
            "variation within and between countries [4,5]. The World Health Organization (WHO) does "
            "not recommend a single target rate for individual hospitals; instead, it emphasizes "
            "assessment in clinically meaningful obstetric populations [3]."
        ),
        (
            "In the United States, final National Vital Statistics System (NVSS) data documented an "
            "overall cesarean rate of 32.4% in 2024 and a primary cesarean rate of 22.9% [1]. "
            "National reports also show that vaginal birth after previous cesarean has increased "
            "since 2016 [1,2]. These aggregate measures are important for surveillance but cannot "
            "distinguish a change in the composition of the delivering population from a change in "
            "cesarean use within a comparable clinical group."
        ),
        (
            "The Robson Ten-Group Classification System assigns all women to mutually exclusive, "
            "collectively exhaustive groups using parity, previous cesarean, number of fetuses, "
            "presentation, gestational age, and onset of labor [6,7]. WHO recommends it as a global "
            "standard for assessing, monitoring, and comparing cesarean rates [7]. Multicountry and "
            "institutional studies have shown that previous cesarean, nulliparous term cephalic births, "
            "and preterm births often make large contributions [8–11]. However, a national U.S. "
            "analysis applying a transparent, reproducible Robson approximation to comparable "
            "2016–2024 birth-certificate files has not been reported."
        ),
        (
            "We therefore aimed to (1) quantify the overall and group-specific cesarean trends among "
            "U.S.-resident hospital live births from 2016 through 2024; (2) identify the obstetric "
            "populations contributing most to cesarean deliveries in 2024; and (3) decompose the "
            "2016–2024 change into population-share and within-group cesarean-rate components."
        ),
    ]
    for text in background:
        main_texts.append(text)
        add_body_paragraph(doc, text)

    add_section_heading(doc, "Methods", 1)
    add_section_heading(doc, "Study design and data source", 2)
    methods = [
        (
            "We performed a population-based repeated cross-sectional study using the 2016–2024 "
            "NVSS natality public-use files produced by the National Center for Health Statistics "
            "(NCHS). These files are derived from the U.S. Standard Certificate of Live Birth and "
            "include all registered live births [1,16]. The study period begins in 2016 because all "
            "states and the District of Columbia used the 2003 revised birth certificate by then, "
            "improving national comparability [1]. The report follows STROBE and RECORD guidance "
            "for observational studies using routinely collected health data [13,14]."
        ),
        (
            "Annual compressed fixed-width files were obtained directly from the NCHS public-use "
            "repository. Each file was streamed record by record; individual records were not "
            "extracted to disk or retained. Annual source-file names, SHA-256 checksums, member CRCs, "
            "and uncompressed sizes are provided in Additional file 1."
        ),
    ]
    for text in methods:
        main_texts.append(text)
        add_body_paragraph(doc, text)

    add_section_heading(doc, "Study population", 2)
    text = (
        "We included live births to U.S. residents occurring in hospitals, with a delivery method "
        "recorded as vaginal or cesarean. We excluded non-U.S. residents; births outside hospitals or "
        "with unknown facility; records with unknown delivery method; and records lacking variables "
        "needed for the modified Robson classification. We used a complete-case approach for "
        "classification because the outcome and grouping variables are categorical and no defensible "
        "imputation model was available. Classification completeness was reported for every year."
    )
    main_texts.append(text)
    add_body_paragraph(doc, text)

    add_section_heading(doc, "Outcome and modified Robson classification", 2)
    outcome_paragraphs = [
        (
            "The primary outcome was cesarean delivery. The primary exposure for temporal analyses "
            "was calendar year. Modified Robson groups were derived from plurality, fetal presentation, "
            "the obstetric estimate of gestational age, live-birth order, number of previous cesareans, "
            "induction of labor, method of delivery, and trial of labor. The operational algorithm and "
            "source-field mapping are shown in Supplementary Table S1."
        ),
        (
            "Parity was approximated from live-birth order. A recorded previous cesarean overrode a "
            "first-live-birth code because a uterine scar establishes a prior delivery, including a "
            "possible non-live birth. Among singleton cephalic term births without a previous cesarean, "
            "induction marked induced labor. If induction was recorded as no, vaginal births and "
            "cesareans with a trial of labor were classified as spontaneous labor; cesareans without a "
            "trial of labor were classified as prelabor cesareans. Records with induction recorded as "
            "yes and trial of labor recorded as no were retained as induced births under a prespecified "
            "hierarchy and counted as data conflicts."
        ),
        (
            "The NVSS presentation field contains cephalic, breech, and other categories. We used "
            "“other” for modified group 9. This category does not map exactly to the transverse or "
            "oblique lie specified by the original Robson system; consequently, all analyses are "
            "explicitly labeled modified Robson, group 9 is interpreted cautiously, and a sensitivity "
            "analysis excluded group 9."
        ),
    ]
    for paragraph_text in outcome_paragraphs:
        main_texts.append(paragraph_text)
        add_body_paragraph(doc, paragraph_text)

    add_section_heading(doc, "Statistical analysis", 2)
    statistics = [
        (
            "For each year and group, we calculated the number of births, population share, number of "
            "cesareans, group-specific cesarean rate, and relative contribution to all cesareans. "
            "Wilson 95% confidence intervals were calculated for proportions. Groups 2 and 4 were "
            "subdivided into induced labor (2a and 4a) and prelabor cesarean (2b and 4b)."
        ),
        (
            "We modeled the annual cesarean count with a log-linear quasi-Poisson model, using the "
            "logarithm of classified births as an offset and centered calendar year as a continuous "
            "predictor. Pearson dispersion was estimated across annual observations and bounded below "
            "at 1. Results are expressed as annual percent change (APC) with 95% confidence intervals. "
            "Because the data represent a national census of eligible records rather than a sample, "
            "we prioritized absolute percentage-point changes and treated model-based uncertainty as "
            "a summary of temporal fit rather than sampling uncertainty."
        ),
        (
            "A symmetric Kitagawa decomposition separated the 2016–2024 absolute change into a "
            "population-share effect, Σ(p2024−p2016)(r2024+r2016)/2, and a within-group rate effect, "
            "Σ(r2024−r2016)(p2024+p2016)/2, where p is group population share and r is the group-specific "
            "cesarean rate [15]. Sensitivity analyses excluded modified group 9 and refitted the overall "
            "trend after omitting 2020 and 2021. All tests were two-sided with α=0.05. Analyses used "
            "Python 3.12, NumPy 2.3.5, SciPy 1.17.0, and Matplotlib 3.10.8."
        ),
    ]
    for text in statistics:
        main_texts.append(text)
        add_body_paragraph(doc, text)

    add_section_heading(doc, "Data-quality and reproducibility checks", 2)
    text = (
        "We reconciled the sum of group counts with the classified analytic population and the sum of "
        "group cesareans with the annual cesarean numerator. The decomposition was required to sum to "
        "the observed absolute rate change. We compared the 2024 U.S.-resident raw record count with "
        "the final NCHS total. The analysis code, annual aggregate JSON files, a machine-readable results "
        "workbook, and high-resolution figures accompany this manuscript; no person-level data are redistributed."
    )
    main_texts.append(text)
    add_body_paragraph(doc, text)

    add_section_heading(doc, "Results", 1)
    add_section_heading(doc, "Study population and completeness", 2)
    total_classified = results["metadata"]["total_classified_births"]
    total_cs = results["metadata"]["total_cesarean_deliveries"]
    text = (
        f"Across 2016–2024, {total_classified:,} births were classified and {total_cs:,} were cesarean "
        f"deliveries. Annual classification completeness ranged from 99.00% in 2016 to 99.58% in 2020 "
        f"and was 99.48% in 2024. The 2024 source file contained 3,638,436 records; after excluding "
        f"9,502 non-U.S. residents, the remaining 3,628,934 U.S.-resident births exactly matched the "
        f"final NCHS total [1]. Among U.S.-resident hospital births, 3,539,096 had a known delivery "
        f"method and 3,520,814 were classifiable (Figure 1)."
    )
    main_texts.append(text)
    add_body_paragraph(doc, text)
    add_figure(
        doc,
        image_path=figure_dir / "figure_1_study_flow.png",
        caption_title="Figure 1 Selection of the 2024 analytic population.",
        legend=(
            "Sequential exclusions are shown at the right of each arrow. The analytic population "
            "includes U.S.-resident hospital live births with known delivery method and sufficient "
            "variables for modified Robson classification. Source: CDC/NCHS NVSS natality public-use file."
        ),
        width_inches=5.5,
    )

    add_section_heading(doc, "Overall trend", 2)
    primary_trend = next(
        row for row in results["trend_models"] if row["model"] == "Overall primary"
    )
    sensitivity_2020 = next(
        row
        for row in results["trend_models"]
        if row["model"] == "Overall excluding 2020-2021"
    )
    text = (
        "The cesarean rate in the classified hospital population was 32.29% in 2016, reached a low "
        "of 32.14% in 2019, and increased to 33.12% in 2024, an absolute change of 0.84 percentage "
        f"points (Table 1 and Figure 2). The model-estimated APC was "
        f"{primary_trend['annual_percent_change']:.3f}% "
        f"(95% CI, {primary_trend['ci_lower']:.3f}%–{primary_trend['ci_upper']:.3f}%; P<0.001). "
        f"After excluding 2020 and 2021, the APC was {sensitivity_2020['annual_percent_change']:.3f}% "
        f"(95% CI, {sensitivity_2020['ci_lower']:.3f}%–{sensitivity_2020['ci_upper']:.3f}%)."
    )
    main_texts.append(text)
    add_body_paragraph(doc, text)

    annual_rows = [
        [
            str(row["year"]),
            f"{row['classified']:,}",
            f"{row['classification_completeness'] * 100:.2f}",
            f"{row['cesarean']:,}",
            f"{row['cesarean_rate'] * 100:.2f}",
            f"{row['cesarean_rate_excluding_group9'] * 100:.2f}",
        ]
        for row in results["annual"]
    ]
    add_table(
        doc,
        title="Table 1 Annual analytic population and cesarean delivery rate",
        headers=[
            "Year",
            "Classified births, n",
            "Complete, %",
            "Cesareans, n",
            "Cesarean rate, %",
            "Rate excluding group 9, %",
        ],
        rows=annual_rows,
        widths_cm=[1.5, 3.0, 2.4, 3.0, 3.0, 3.4],
        notes=[
            "Complete indicates the proportion of U.S.-resident hospital live births with known delivery method that could be assigned to a modified Robson group.",
            "Group 9 is the modified category based on the NVSS “other presentation” field.",
        ],
    )
    add_figure(
        doc,
        image_path=figure_dir / "figure_2_overall_trend.png",
        caption_title="Figure 2 Cesarean delivery rate, 2016–2024.",
        legend=(
            "The primary series includes all modified Robson-classified births. The sensitivity "
            "series excludes modified group 9. Rates are based on U.S.-resident hospital live births."
        ),
    )

    add_section_heading(doc, "Modified Robson profile in 2024", 2)
    rows_2024 = [row for row in results["group_year"] if row["year"] == 2024]
    text = (
        "Group 5 was the largest contributor in 2024, accounting for 32.21% of all cesareans, "
        "followed by group 2 (21.60%), group 10 (10.09%), and group 4 (9.46%) (Table 2 and Figure 3). "
        "Group-specific cesarean rates were highest in breech groups 6 and 7 (96.86% and 94.94%), "
        "followed by group 5 (83.51%) and multiple pregnancy group 8 (75.09%). These rates describe "
        "clinical populations and should not be interpreted as group-specific targets."
    )
    main_texts.append(text)
    add_body_paragraph(doc, text)
    table2_rows = [
        [
            row["group"],
            GROUP_DEFINITIONS[row["group"]],
            f"{row['n']:,}",
            f"{row['population_share'] * 100:.2f}",
            f"{row['cesarean_rate'] * 100:.2f}",
            f"{row['relative_contribution'] * 100:.2f}",
        ]
        for row in rows_2024
    ]
    add_table(
        doc,
        title="Table 2 Modified Robson group profile in 2024",
        headers=[
            "Group",
            "Operational definition",
            "Births, n",
            "Population share, %",
            "Cesarean rate, %",
            "Relative contribution, %",
        ],
        rows=table2_rows,
        widths_cm=[1.2, 6.7, 2.5, 2.6, 2.5, 2.9],
        notes=[
            "Relative contribution is the proportion of all cesarean deliveries occurring in the group.",
            "Modified group 9 uses the NVSS “other presentation” category and does not map exactly to transverse/oblique lie.",
        ],
    )
    add_figure(
        doc,
        image_path=figure_dir / "figure_3_2024_contribution.png",
        caption_title="Figure 3 Relative contribution of modified Robson groups, 2024.",
        legend=(
            "Bars show the percentage of all cesarean deliveries occurring within each group. "
            "Groups are ordered by contribution. The asterisk marks the modified definition of group 9."
        ),
    )

    add_section_heading(doc, "Population shifts and decomposition", 2)
    text = (
        "Between 2016 and 2024, the share of group 2 rose from 13.49% to 18.34%, while its "
        "cesarean rate declined from 44.54% to 39.02%. The share of group 4 similarly rose from "
        "14.07% to 17.27%, while its cesarean rate declined from 22.44% to 18.14%. Group 5 remained "
        "nearly unchanged in population share (12.82% to 12.77%) but its cesarean rate declined from "
        "86.95% to 83.51%. In contrast, group 10 increased in both population share (6.97% to 7.64%) "
        "and cesarean rate (38.82% to 43.76%)."
    )
    main_texts.append(text)
    add_body_paragraph(doc, text)
    text = (
        "The Kitagawa decomposition exactly reproduced the 0.835-percentage-point observed increase "
        "(Table 3 and Figure 4). Group 2 contributed +1.146 percentage points: a +2.025-point "
        "population-share effect was partly offset by a −0.879-point within-group rate effect. "
        "Group 10 contributed +0.636 points through both population-share (+0.275) and within-group "
        "rate (+0.361) effects. Group 5 offset the increase by 0.480 points, mainly through its lower "
        "within-group rate. Groups 1, 8, and modified 9 also had net negative contributions."
    )
    main_texts.append(text)
    add_body_paragraph(doc, text)
    table3_rows = [
        [
            row["group"],
            f"{row['population_share_change_pp']:+.3f}",
            f"{row['cesarean_rate_change_pp']:+.3f}",
            f"{row['composition_effect_pp']:+.3f}",
            f"{row['rate_effect_pp']:+.3f}",
            f"{row['total_effect_pp']:+.3f}",
        ]
        for row in results["decomposition"]
    ]
    add_table(
        doc,
        title="Table 3 Decomposition of change from 2016 to 2024",
        headers=[
            "Group",
            "Population-share change, pp",
            "Cesarean-rate change, pp",
            "Population-share effect, pp",
            "Within-group rate effect, pp",
            "Total effect, pp",
        ],
        rows=table3_rows,
        widths_cm=[1.3, 3.5, 3.4, 3.5, 3.7, 2.8],
        notes=[
            "pp, percentage points. Effects are symmetric Kitagawa components. Positive values increased and negative values reduced the overall cesarean rate.",
            "Column totals may differ in the last decimal place because of rounding; unrounded effects sum to +0.835 percentage points.",
        ],
    )
    add_figure(
        doc,
        image_path=figure_dir / "figure_4_decomposition.png",
        caption_title="Figure 4 Decomposition of the cesarean rate change, 2016–2024.",
        legend=(
            "Paired bars show each group’s population-share and within-group rate effects in "
            "percentage points. Positive values increased the national rate; negative values offset it."
        ),
    )

    add_section_heading(doc, "Subgroups and sensitivity analyses", 2)
    text = (
        "The expansion of group 2 was concentrated in induced nulliparous term births (group 2a), "
        "whose population share increased from 10.80% to 15.76%, while its cesarean rate declined "
        "from 30.75% to 29.06%. The share of prelabor cesareans in nulliparous term births (group 2b) "
        "decreased slightly from 2.69% to 2.57%. Group 4a increased from 11.62% to 15.04% of the "
        "population, while group 4b decreased from 2.45% to 2.23% (Supplementary Table S2)."
    )
    main_texts.append(text)
    add_body_paragraph(doc, text)
    sensitivity_group9 = next(
        row
        for row in results["trend_models"]
        if row["model"] == "Overall excluding modified group 9"
    )
    text = (
        "After excluding modified group 9, the cesarean rate increased from 31.97% in 2016 to "
        f"33.01% in 2024 (+1.04 percentage points), with an APC of "
        f"{sensitivity_group9['annual_percent_change']:.3f}% "
        f"(95% CI, {sensitivity_group9['ci_lower']:.3f}%–{sensitivity_group9['ci_upper']:.3f}%; P<0.001). "
        "Thus, the principal conclusion—an increase driven mainly by groups 2 and 10—did not depend "
        "on the modified group 9 mapping."
    )
    main_texts.append(text)
    add_body_paragraph(doc, text)

    add_section_heading(doc, "Discussion", 1)
    add_section_heading(doc, "Principal findings", 2)
    discussion = [
        (
            "In this national repeated cross-sectional analysis of more than 32.6 million classified "
            "hospital live births, the cesarean rate increased modestly by 0.84 percentage points "
            "between 2016 and 2024. The central finding is that this was not an across-the-board "
            "increase in cesarean use. The population shares of groups 2 and 4 expanded while their "
            "group-specific rates fell, and the rate in group 5 also declined. The overall increase "
            "instead reflected a strong compositional shift toward group 2 and a rising contribution "
            "from preterm singleton cephalic births in group 10."
        ),
        (
            "Group 5 remained the largest contributor to all cesareans, but its relative contribution "
            "fell from 34.53% to 32.21% and its cesarean rate decreased by 3.44 percentage points. "
            "This direction is consistent with NCHS evidence that vaginal birth after previous "
            "cesarean increased nationally from 2016 through 2024 [1,2]. The result suggests that "
            "previous cesarean remains central to the national burden while also showing that the "
            "recent rise cannot be attributed to group 5 alone."
        ),
    ]
    for text in discussion:
        main_texts.append(text)
        add_body_paragraph(doc, text)

    add_section_heading(doc, "Comparison with previous research", 2)
    comparison = [
        (
            "WHO multicountry analyses identified groups 2 and 5 as major contributors to rising "
            "cesarean rates [8], and a 10-year Irish study found that nulliparous induced or prelabor "
            "groups and previous cesarean were principal drivers [9]. Our U.S. results agree that "
            "groups 2 and 5 are quantitatively important, but the decomposition adds a critical "
            "distinction: the increased contribution of group 2 arose from a larger group size, not "
            "a higher group-specific cesarean rate."
        ),
        (
            "The increase in group 2 was almost entirely explained by group 2a, not group 2b. This "
            "finding does not imply that induction causes the national cesarean increase: women "
            "selected for induction differ in clinical indication and risk, and the birth certificate "
            "does not capture all indications. Instead, it shows that induced nulliparous term births "
            "became a substantially larger part of the delivering population while their cesarean "
            "rate declined. That distinction is important when national trends are interpreted."
        ),
        (
            "Group 10 increased through both composition and within-group rate effects. Because this "
            "group includes heterogeneous spontaneous and medically indicated preterm births, the "
            "result should not be interpreted as evidence of avoidable cesareans. It identifies a "
            "population requiring more detailed analyses with gestational-age strata, indications, "
            "hospital capability, and maternal or fetal conditions that are unavailable in the "
            "public-use file."
        ),
    ]
    for text in comparison:
        main_texts.append(text)
        add_body_paragraph(doc, text)

    add_section_heading(doc, "Clinical and policy implications", 2)
    implication = (
        "National quality improvement should pair the overall cesarean rate with standardized "
        "population-specific metrics. For nulliparous term cephalic pregnancies, surveillance should "
        "separate spontaneous labor, induction, and prelabor cesarean and evaluate the indication and "
        "timing of induction rather than treating all group 2 births alike. For women with previous "
        "cesarean, evidence-based counseling and access to trial of labor remain relevant, while "
        "recognizing individual contraindications. For group 10, prevention of medically avoidable "
        "preterm birth and review of indication-specific delivery pathways may be more informative "
        "than a cesarean-rate target. Breech, multiple, and other high-risk groups should be assessed "
        "for appropriateness and outcomes, not judged solely by their high cesarean rates."
    )
    main_texts.append(implication)
    add_body_paragraph(doc, implication)

    add_section_heading(doc, "Strengths and limitations", 2)
    limitations = [
        (
            "Strengths include national coverage, consistent 2016–2024 certificate revision, a "
            "prespecified and fully reproducible classification algorithm, explicit data-quality "
            "accounting, separate assessment of group size and group-specific rate, and a decomposition "
            "that exactly reconciled to the observed national change. The raw 2024 U.S.-resident count "
            "also reproduced the final NCHS total."
        ),
        (
            "Several limitations are important. First, birth certificates are administrative records "
            "and some clinical fields may be incomplete or misclassified. Second, live-birth order is "
            "an imperfect proxy for parity because prior fetal deaths and other non-live deliveries "
            "are not fully represented; a previous-cesarean field partly mitigated but did not eliminate "
            "this limitation. Third, onset of labor was inferred from induction and trial-of-labor "
            "fields, and conflicting induction/trial records were resolved by a prespecified hierarchy."
        ),
        (
            "Fourth, the “other presentation” field produced a modified group 9 that is broader than "
            "transverse or oblique lie; its relatively low cesarean rate confirms imperfect mapping. "
            "The sensitivity analysis excluding this group yielded a slightly larger, not smaller, "
            "increase. Fifth, the study includes live births only and excludes fetal deaths; it also "
            "lacks detailed indications, hospital identifiers, clinician practice, labor-management "
            "processes, maternal condition severity, and longitudinal linkage. Finally, the ecological "
            "temporal design cannot establish why group sizes or rates changed, and very large counts "
            "make clinically small differences statistically detectable."
        ),
    ]
    for text in limitations:
        main_texts.append(text)
        add_body_paragraph(doc, text)

    add_section_heading(doc, "Conclusions", 1)
    conclusion = (
        "Among U.S.-resident hospital live births classified with a modified Robson system, the "
        "cesarean delivery rate increased from 32.29% to 33.12% between 2016 and 2024. The increase "
        "was driven mainly by a larger nulliparous term induced population and by a growing contribution "
        "from preterm singleton cephalic births, while group-specific rates declined in groups 2, 4, "
        "and 5. Future national surveillance should report both population composition and within-group "
        "cesarean use and should validate the classification with data sources that contain full parity, "
        "presentation, labor-onset, indication, and hospital information."
    )
    main_texts.append(conclusion)
    add_body_paragraph(doc, conclusion)

    add_section_heading(doc, "List of abbreviations", 1)
    add_body_paragraph(
        doc,
        "APC, annual percent change; CDC, Centers for Disease Control and Prevention; "
        "CI, confidence interval; NCHS, National Center for Health Statistics; "
        "NVSS, National Vital Statistics System; WHO, World Health Organization.",
    )

    add_section_heading(doc, "Declarations", 1)
    add_section_heading(doc, "Ethics approval and consent to participate", 2)
    add_confirmation_paragraph(
        doc,
        "",
        (
            "The analyses used publicly available, deidentified natality public-use data and involved "
            "no direct participant contact. No individual informed consent was required. Insert or "
            "confirm the local institutional ethics determination, waiver, committee name, and "
            "reference number if applicable."
        ),
    )
    add_section_heading(doc, "Consent for publication", 2)
    add_body_paragraph(doc, "Not applicable.")
    add_section_heading(doc, "Availability of data and materials", 2)
    data_paragraph = doc.add_paragraph()
    data_paragraph.add_run(
        "The annual natality public-use files and user guides analyzed in this study are available "
        "from the CDC/NCHS Vital Statistics Online repository: "
    )
    add_hyperlink(
        data_paragraph,
        "https://www.cdc.gov/nchs/data_access/vitalstatsonline.htm",
        "https://www.cdc.gov/nchs/data_access/vitalstatsonline.htm",
    )
    data_paragraph.add_run(
        ". Aggregated outputs, source-file checksums, analysis code, and the complete result workbook "
        "are included as additional files with this manuscript."
    )
    add_section_heading(doc, "Competing interests", 2)
    add_confirmation_paragraph(doc, "", "The authors declare that they have no competing interests.")
    add_section_heading(doc, "Funding", 2)
    add_body_paragraph(doc, "The authors received no specific funding for this work.")
    add_section_heading(doc, "Authors’ contributions", 2)
    add_confirmation_paragraph(
        doc,
        "",
        (
            "CZ conceived the study, developed the analysis plan, verified variables, interpreted "
            "the results, and drafted the manuscript. JX supervised the study, reviewed clinical "
            "interpretation, validated the results, and critically revised the manuscript. Both "
            "authors approved the final manuscript."
        ),
    )
    add_section_heading(doc, "Acknowledgements", 2)
    add_body_paragraph(doc, "Not applicable.")
    add_section_heading(doc, "Use of generative artificial intelligence", 2)
    add_confirmation_paragraph(
        doc,
        "",
        (
            "OpenAI ChatGPT was used to assist with analysis-code drafting, English-language editing, "
            "figure preparation, and document formatting. The authors verified all variable definitions, "
            "source files, statistical outputs, interpretations, and final text and take full responsibility "
            "for the work. Confirm this wording after completing author review."
        ),
    )

    add_section_heading(doc, "References", 1)
    references = [
        "1. Osterman MJK, Hamilton BE, Martin JA, Driscoll AK, Valenzuela CP. Births: Final Data for 2024. Natl Vital Stat Rep. 2026;75(2):1–48.",
        "2. Osterman MJK. Changes in primary and repeat cesarean delivery: United States, 2016–2021. Vital Statistics Rapid Release; no 21. Hyattsville, MD: National Center for Health Statistics; 2022. doi:10.15620/cdc:117432.",
        "3. World Health Organization. WHO statement on caesarean section rates. Geneva: World Health Organization; 2015. WHO/RHR/15.02.",
        "4. Betrán AP, Ye J, Moller AB, Zhang J, Gülmezoglu AM, Torloni MR. The increasing trend in caesarean section rates: global, regional and national estimates: 1990–2014. PLoS One. 2016;11(2):e0148343. doi:10.1371/journal.pone.0148343.",
        "5. Betran AP, Ye J, Moller AB, Souza JP, Zhang J. Trends and projections of caesarean section rates: global and regional estimates. BMJ Glob Health. 2021;6:e005671. doi:10.1136/bmjgh-2021-005671.",
        "6. Robson MS. Can we reduce the caesarean section rate? Best Pract Res Clin Obstet Gynaecol. 2001;15(1):179–194. doi:10.1053/beog.2000.0156.",
        "7. World Health Organization. Robson Classification: Implementation Manual. Geneva: World Health Organization; 2017. ISBN 978-92-4-151319-7.",
        "8. Vogel JP, Betrán AP, Vindevoghel N, Souza JP, Torloni MR, Zhang J, et al. Use of the Robson classification to assess caesarean section trends in 21 countries: a secondary analysis of two WHO multicountry surveys. Lancet Glob Health. 2015;3(5):e260–e270. doi:10.1016/S2214-109X(15)70094-X.",
        "9. Crosby DA, Murphy MM, Segurado R, Byrne F, Mahony R, Robson M, et al. Cesarean delivery rates using Robson classification system in Ireland: what can we learn? Eur J Obstet Gynecol Reprod Biol. 2019;236:121–126. doi:10.1016/j.ejogrb.2019.03.011.",
        "10. Betrán AP, Vindevoghel N, Souza JP, Gülmezoglu AM, Torloni MR. A systematic review of the Robson classification for caesarean section: what works, doesn’t work and how to improve it. PLoS One. 2014;9(6):e97769. doi:10.1371/journal.pone.0097769.",
        "11. Boatin AA, Cullinane F, Torloni MR, Betrán AP. Audit and feedback using the Robson classification to reduce caesarean section rates: a systematic review. BJOG. 2018;125(1):36–42. doi:10.1111/1471-0528.14774.",
        "12. Keag OE, Norman JE, Stock SJ. Long-term risks and benefits associated with cesarean delivery for mother, baby, and subsequent pregnancies: systematic review and meta-analysis. PLoS Med. 2018;15(1):e1002494. doi:10.1371/journal.pmed.1002494.",
        "13. von Elm E, Altman DG, Egger M, Pocock SJ, Gøtzsche PC, Vandenbroucke JP. The Strengthening the Reporting of Observational Studies in Epidemiology (STROBE) Statement: guidelines for reporting observational studies. Ann Intern Med. 2007;147(8):573–577. doi:10.7326/0003-4819-147-8-200710160-00010.",
        "14. Benchimol EI, Smeeth L, Guttmann A, Harron K, Moher D, Petersen I, et al. The REporting of studies Conducted using Observational Routinely-collected health Data (RECORD) Statement. PLoS Med. 2015;12(10):e1001885. doi:10.1371/journal.pmed.1001885.",
        "15. Kitagawa EM. Components of a difference between two rates. J Am Stat Assoc. 1955;50(272):1168–1194.",
        "16. National Center for Health Statistics. User Guide to the 2024 Natality Public Use File. Hyattsville, MD: National Center for Health Statistics; 2025. https://ftp.cdc.gov/pub/Health_Statistics/NCHS/Dataset_Documentation/DVS/natality/UserGuide2024.pdf. Accessed 27 Jul 2026.",
    ]
    for reference in references:
        paragraph = doc.add_paragraph(reference)
        paragraph.paragraph_format.left_indent = Cm(0.6)
        paragraph.paragraph_format.first_line_indent = Cm(-0.6)
        paragraph.paragraph_format.line_spacing_rule = WD_LINE_SPACING.SINGLE
        paragraph.paragraph_format.space_after = Pt(4)

    add_section_heading(doc, "Supplementary material included in the manuscript file", 1)
    add_section_heading(doc, "Supplementary Table S1. Modified Robson operational definitions", 2)
    operational_rows = [
        ["1", GROUP_DEFINITIONS["1"], "Singleton; cephalic; ≥37 weeks; no previous cesarean; nulliparous proxy; spontaneous labor"],
        ["2", GROUP_DEFINITIONS["2"], "As group 1, but induced labor (2a) or prelabor cesarean (2b)"],
        ["3", GROUP_DEFINITIONS["3"], "Singleton; cephalic; ≥37 weeks; no previous cesarean; multiparous proxy; spontaneous labor"],
        ["4", GROUP_DEFINITIONS["4"], "As group 3, but induced labor (4a) or prelabor cesarean (4b)"],
        ["5", GROUP_DEFINITIONS["5"], "Singleton; cephalic; ≥37 weeks; one or more previous cesareans"],
        ["6", GROUP_DEFINITIONS["6"], "Singleton; breech; nulliparous proxy"],
        ["7", GROUP_DEFINITIONS["7"], "Singleton; breech; multiparous proxy"],
        ["8", GROUP_DEFINITIONS["8"], "Plurality >1, regardless of other characteristics"],
        ["9", GROUP_DEFINITIONS["9"], "Singleton; NVSS presentation category “other”"],
        ["10", GROUP_DEFINITIONS["10"], "Singleton; cephalic; <37 weeks"],
    ]
    add_table(
        doc,
        title="Supplementary Table S1 Modified Robson operational definitions",
        headers=["Group", "Label", "Algorithm"],
        rows=operational_rows,
        widths_cm=[1.4, 7.0, 9.8],
        notes=[
            "Parity proxy used live-birth order, with any recorded previous cesarean overriding a first-live-birth code.",
            "Source fields and fixed-width positions are documented in the accompanying analysis code.",
        ],
    )

    subgroup_selected = [
        row for row in results["subgroup_year"] if row["year"] in {2016, 2024}
    ]
    add_table(
        doc,
        title="Supplementary Table S2 Subgroups 2a, 2b, 4a, and 4b",
        headers=[
            "Year",
            "Subgroup",
            "Births, n",
            "Population share, %",
            "Cesareans, n",
            "Cesarean rate, %",
            "Relative contribution, %",
        ],
        rows=[
            [
                str(row["year"]),
                row["subgroup"],
                f"{row['n']:,}",
                f"{row['population_share'] * 100:.2f}",
                f"{row['cesarean']:,}",
                f"{row['cesarean_rate'] * 100:.2f}",
                f"{row['relative_contribution'] * 100:.2f}",
            ]
            for row in subgroup_selected
        ],
        widths_cm=[1.5, 1.8, 2.6, 3.0, 2.6, 2.8, 3.2],
        notes=[
            "2a and 4a indicate induced labor; 2b and 4b indicate cesarean before labor in the corresponding term singleton cephalic parity groups.",
        ],
    )

    add_table(
        doc,
        title="Supplementary Table S3 Quasi-Poisson trend models",
        headers=["Model", "Years", "APC, %", "95% CI", "P value"],
        rows=[
            [
                row["model"],
                f"{row['first_year']}–{row['last_year']} (n={row['n_time_points']})",
                f"{row['annual_percent_change']:.3f}",
                f"{row['ci_lower']:.3f} to {row['ci_upper']:.3f}",
                "<0.001" if row["p_value"] < 0.001 else f"{row['p_value']:.3f}",
            ]
            for row in results["trend_models"]
        ],
        widths_cm=[6.5, 3.2, 2.6, 3.4, 2.4],
        notes=[
            "APC, annual percent change. Models used annual cesarean counts with classified births as the offset and Pearson-scaled standard errors.",
        ],
    )

    add_table(
        doc,
        title="Supplementary Table S4 Classification completeness and conflicts",
        headers=[
            "Year",
            "Known delivery",
            "Classified",
            "Complete, %",
            "First-live-birth/previous-cesarean conflict",
            "Induction-yes/trial-no conflict",
        ],
        rows=[
            [
                str(row["year"]),
                f"{row['known_delivery']:,}",
                f"{row['classified']:,}",
                f"{row['classification_completeness'] * 100:.2f}",
                f"{row['conflict_first_live_birth_with_previous_cesarean']:,}",
                f"{row['conflict_induction_yes_trial_no']:,}",
            ]
            for row in results["quality"]
        ],
        widths_cm=[1.4, 3.0, 3.0, 2.2, 4.7, 4.0],
        notes=[
            "Conflicts were retained under prespecified rules and are presented for auditability.",
        ],
    )

    add_figure(
        doc,
        image_path=figure_dir / "supplementary_figure_1_group_trends.png",
        caption_title="Supplementary Figure S1 Group-specific cesarean delivery rates, 2016–2024.",
        legend=(
            "Each panel uses its own y-axis scale to make within-group temporal change visible. "
            "Modified group 9 uses the NVSS “other presentation” category."
        ),
        width_inches=6.4,
    )

    output_path.parent.mkdir(parents=True, exist_ok=True)
    doc.save(output_path)


def build_cover_letter(output_path: Path) -> None:
    doc = Document()
    configure_document(doc, short_title="Cover letter")
    section = doc.sections[0]
    # Cover letters do not need line numbering.
    ln_num = section._sectPr.find(qn("w:lnNumType"))
    if ln_num is not None:
        section._sectPr.remove(ln_num)

    add_title_band(doc, "COVER LETTER")
    paragraph = doc.add_paragraph()
    paragraph.paragraph_format.line_spacing_rule = WD_LINE_SPACING.SINGLE
    paragraph.add_run("27 July 2026")
    doc.add_paragraph()
    add_body_paragraph(doc, "Dear Editors of BMC Pregnancy and Childbirth,")

    paragraphs = [
        (
            f"We submit the Research Article entitled “{TITLE}” for consideration in BMC Pregnancy "
            "and Childbirth."
        ),
        (
            "Using complete 2016–2024 U.S. national natality public-use files, we classified more "
            "than 32.6 million U.S.-resident hospital live births with a transparent modified Robson "
            "algorithm. The cesarean rate increased by 0.84 percentage points, but decomposition showed "
            "that the increase did not reflect an across-the-board rise in group-specific cesarean use. "
            "It was concentrated in a compositional expansion of induced nulliparous term births and "
            "a growing contribution from preterm singleton cephalic births. Previous cesarean remained "
            "the largest contributor but offset, rather than drove, the increase."
        ),
        (
            "The manuscript is aligned with the journal’s scope in labor, maternity care, and trends "
            "in pregnancy and childbirth. Its national coverage, reproducible classification, explicit "
            "data-quality audit, and separation of population composition from within-group practice "
            "provide a distinct contribution beyond aggregate U.S. cesarean surveillance."
        ),
        (
            "All source data are publicly available from CDC/NCHS. We include the full analysis code, "
            "annual aggregate outputs, a machine-readable results workbook, source-file checksums, and "
            "300-dpi figures. The manuscript follows STROBE and RECORD guidance."
        ),
    ]
    for text in paragraphs:
        add_body_paragraph(doc, text)

    add_confirmation_paragraph(
        doc,
        "",
        (
            "Confirm that all authors have approved the manuscript; it has not been published or "
            "submitted elsewhere; the competing-interest declaration is complete; the local ethics "
            "determination is correct; and the generative-AI disclosure is acceptable."
        ),
    )
    add_body_paragraph(doc, "Thank you for considering our work.")
    add_body_paragraph(doc, "Sincerely,")
    signature = doc.add_paragraph()
    signature.paragraph_format.line_spacing_rule = WD_LINE_SPACING.SINGLE
    signature.add_run("Jixue Xiao\n").bold = True
    signature.add_run("Corresponding author\n")
    signature.add_run("Liaocheng Second People’s Hospital\n")
    signature.add_run("Liaocheng, Shandong, China\n")
    add_hyperlink(signature, "17588269328@163.com", "mailto:17588269328@163.com")

    # Keep the submission letter compact enough to remain on one page.
    for cover_paragraph in doc.paragraphs:
        cover_paragraph.paragraph_format.line_spacing = 1.15
        cover_paragraph.paragraph_format.space_after = Pt(5)
    signature.paragraph_format.line_spacing_rule = WD_LINE_SPACING.SINGLE
    signature.paragraph_format.space_after = Pt(0)

    output_path.parent.mkdir(parents=True, exist_ok=True)
    doc.save(output_path)


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--results",
        type=Path,
        default=Path("outputs/analysis/analysis_results.json"),
    )
    parser.add_argument(
        "--figure-dir",
        type=Path,
        default=Path("outputs/analysis"),
    )
    parser.add_argument(
        "--output-dir",
        type=Path,
        default=Path("outputs/final"),
    )
    args = parser.parse_args()
    with args.results.open(encoding="utf-8") as handle:
        results = json.load(handle)
    build_manuscript(
        results,
        args.figure_dir,
        args.output_dir / "SCI_Manuscript_Modified_Robson_US_2016_2024.docx",
    )
    build_cover_letter(args.output_dir / "Cover_Letter_BMC_Pregnancy_Childbirth.docx")
    print(
        json.dumps(
            {
                "manuscript": str(
                    args.output_dir / "SCI_Manuscript_Modified_Robson_US_2016_2024.docx"
                ),
                "cover_letter": str(
                    args.output_dir / "Cover_Letter_BMC_Pregnancy_Childbirth.docx"
                ),
            }
        )
    )


if __name__ == "__main__":
    main()
