#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Tth Word 报告的版式收口：中文字体、页眉 Logo、页脚页码、结论框。"""
import os
from docx import Document
from docx.shared import Pt, Mm, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_LINE_SPACING
from docx.oxml import OxmlElement
from docx.oxml.ns import qn

ROOT = '/Users/liuxinyuan/Desktop/Hermes输出-工作类'
DOC = os.path.join(ROOT, '资料/Tth酶体系引物探针设计_关键结果_20261101_V01.docx')
LOGO = os.path.expanduser('~/work/公司资料/logo_transparent.png')

doc = Document(DOC)
sec = doc.sections[0]
sec.top_margin = Mm(24)
sec.bottom_margin = Mm(22)
sec.left_margin = Mm(23)
sec.right_margin = Mm(23)
sec.header_distance = Mm(8)
sec.footer_distance = Mm(8)


def set_eastasia(run_or_style, font_name):
    """run 或 style 的 font 设置。"""
    rpr = run_or_style.element.get_or_add_rPr() if hasattr(run_or_style, 'element') else run_or_style.element.get_or_add_rPr()
    rfonts = rpr.find(qn('w:rFonts'))
    if rfonts is None:
        rfonts = OxmlElement('w:rFonts')
        rpr.append(rfonts)
    rfonts.set(qn('w:eastAsia'), font_name)


def style_font(style, name, size=None, bold=None, color=None):
    style.font.name = name
    set_eastasia(style, name)
    if size is not None:
        style.font.size = Pt(size)
    if bold is not None:
        style.font.bold = bold
    if color is not None:
        style.font.color.rgb = RGBColor.from_string(color)


def p_border_bottom(paragraph, color='D8E2EE', sz='6'):
    pPr = paragraph._p.get_or_add_pPr()
    pBdr = pPr.find(qn('w:pBdr'))
    if pBdr is None:
        pBdr = OxmlElement('w:pBdr')
        pPr.append(pBdr)
    bottom = OxmlElement('w:bottom')
    bottom.set(qn('w:val'), 'single')
    bottom.set(qn('w:sz'), sz)
    bottom.set(qn('w:space'), '4')
    bottom.set(qn('w:color'), color)
    pBdr.append(bottom)


def p_shading(paragraph, fill='EAF2FA'):
    pPr = paragraph._p.get_or_add_pPr()
    shd = OxmlElement('w:shd')
    shd.set(qn('w:fill'), fill)
    pPr.append(shd)


def p_left_border(paragraph, color='2E6DA4', sz='18'):
    pPr = paragraph._p.get_or_add_pPr()
    pBdr = pPr.find(qn('w:pBdr'))
    if pBdr is None:
        pBdr = OxmlElement('w:pBdr')
        pPr.append(pBdr)
    left = OxmlElement('w:left')
    left.set(qn('w:val'), 'single')
    left.set(qn('w:sz'), sz)
    left.set(qn('w:space'), '8')
    left.set(qn('w:color'), color)
    pBdr.append(left)


# 基础样式
for sname in ['Normal', 'BodyCN', 'KeyBox', 'DocTitle', 'SubTitle', 'Refs']:
    if sname in doc.styles:
        s = doc.styles[sname]
        style_font(s, '宋体', 10.5, color='17212E')
        s.paragraph_format.line_spacing = 1.35
        s.paragraph_format.space_after = Pt(3)

body = doc.styles['BodyCN']
body.paragraph_format.first_line_indent = Mm(7.4)
body.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
body.paragraph_format.line_spacing = 1.35
body.paragraph_format.space_after = Pt(3)

if 'KeyBox' in doc.styles:
    kb = doc.styles['KeyBox']
    style_font(kb, '宋体', 10.5, False, '17212E')
    kb.paragraph_format.first_line_indent = Mm(0)
    kb.paragraph_format.left_indent = Mm(2)
    kb.paragraph_format.right_indent = Mm(2)
    kb.paragraph_format.space_before = Pt(7)
    kb.paragraph_format.space_after = Pt(9)
    kb.paragraph_format.line_spacing = 1.35

if 'DocTitle' in doc.styles:
    ts = doc.styles['DocTitle']
    style_font(ts, '微软雅黑', 20, True, '1F4E79')
    ts.paragraph_format.space_before = Pt(3)
    ts.paragraph_format.space_after = Pt(4)

if 'SubTitle' in doc.styles:
    ss = doc.styles['SubTitle']
    style_font(ss, '微软雅黑', 8.5, False, '667085')
    ss.paragraph_format.space_after = Pt(8)

if 'Heading 1' in doc.styles:
    h = doc.styles['Heading 1']
    style_font(h, '微软雅黑', 13, True, '1F4E79')
    h.paragraph_format.space_before = Pt(11)
    h.paragraph_format.space_after = Pt(4)
    h.paragraph_format.keep_with_next = True

if 'Refs' in doc.styles:
    r = doc.styles['Refs']
    style_font(r, '宋体', 8, False, '667085')
    r.paragraph_format.line_spacing = 1.15
    r.paragraph_format.space_before = Pt(9)
    r.paragraph_format.space_after = Pt(0)

# 标题下边线、结论框
for p in doc.paragraphs:
    if p.style.name == 'DocTitle':
        p.alignment = WD_ALIGN_PARAGRAPH.LEFT
        p_border_bottom(p, color='1F4E79', sz='8')
    elif p.style.name == 'KeyBox':
        p_shading(p, 'EAF2FA')
        p_left_border(p, color='2E6DA4', sz='20')
    elif p.style.name == 'Heading 1':
        p_border_bottom(p, color='D8E2EE', sz='4')

# 页眉：真 Logo + 公司名；清空后重建
header = sec.header
hp = header.paragraphs[0]
for r in list(hp.runs):
    r._element.getparent().remove(r._element)
hp.alignment = WD_ALIGN_PARAGRAPH.LEFT
hp.paragraph_format.space_after = Pt(2)
if os.path.exists(LOGO):
    run = hp.add_run()
    run.add_picture(LOGO, width=Mm(23))
    run2 = hp.add_run('    宝锐生物 BIORI BIOTECH · Tth 体系引物探针设计建议')
else:
    run2 = hp.add_run('宝锐生物 BIORI BIOTECH · Tth 体系引物探针设计建议')
run2.font.name = '微软雅黑'
set_eastasia(run2, '微软雅黑')
run2.font.size = Pt(8)
run2.font.color.rgb = RGBColor.from_string('667085')
p_border_bottom(hp, color='D8E2EE', sz='4')

# 页脚：slogan + 中文页码（保留 PAGE/NUMPAGES 字段）
footer = sec.footer
fp = footer.paragraphs[0]
fp.alignment = WD_ALIGN_PARAGRAPH.CENTER
# 删除原有非 field 文本，保留 field 结构；重建为中文
for r in list(fp.runs):
    if not r._element.findall('.//' + qn('w:fldChar')) and not r._element.findall('.//' + qn('w:instrText')):
        r.text = ''
# 按现有结构重写：先看清当前文本，若字段丢失则重建
# 这里直接构造完整页脚，确保无残余 "Page / of"
for r in list(fp.runs):
    r._element.getparent().remove(r._element)
fp.add_run('守护生命健康，缔造美好生活  ｜  内部技术参考  ｜  第 ')
fld1 = OxmlElement('w:fldSimple')
fld1.set(qn('w:instr'), ' PAGE ')
r1 = OxmlElement('w:r')
t1 = OxmlElement('w:t')
t1.text = '1'
r1.append(t1)
fld1.append(r1)
fp._p.append(fld1)
fp.add_run(' 页 / 共 ')
fld2 = OxmlElement('w:fldSimple')
fld2.set(qn('w:instr'), ' NUMPAGES ')
r2 = OxmlElement('w:r')
t2 = OxmlElement('w:t')
t2.text = '2'
r2.append(t2)
fld2.append(r2)
fp._p.append(fld2)
fp.add_run(' 页')
for r in fp.runs:
    r.font.name = '微软雅黑'
    set_eastasia(r, '微软雅黑')
    r.font.size = Pt(8)
    r.font.color.rgb = RGBColor.from_string('667085')

# Word 打开时刷新页码字段
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')

# 文档属性
cp = doc.core_properties
cp.title = 'Tth 体系引物探针设计：关键结果'
cp.subject = 'Tth 一步法 RT-PCR 引物与探针设计建议'
cp.author = '宝锐生物营销中心'
cp.keywords = 'Tth, 引物, 探针, Tm, RT-PCR, 筛选'
cp.comments = '内部技术参考，客户体系参数需实测确认'

doc.save(DOC)
print('SAVED', DOC, os.path.getsize(DOC))
