#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""内容模型 → HTML（供 Chrome 打印 PDF），与 DOCX 同一套字号/字体口径"""
import json
import os
import re
import sys

OUT_HTML = '/tmp/stability.html'
CHAPTERS = [
    ('第一部分  主报告：产品稳定性研究资料', '/tmp/main.json', 'main'),
    ('第二部分  运输稳定性验证资料（2024 年）', '/tmp/trans.json', 'trans'),
    ('第三部分  加速稳定性测试报告', '/tmp/acc.json', 'acc'),
    ('第四部分  冻融稳定性测试报告', '/tmp/frz.json', 'frz'),
]
HDR_KW = ('分组', '样品', '检测项目', '批号', '结果', '项目', '孔数', '名称', '浓度', '时间', '编号', 'Ct')


def augment(m):
    last = {}
    for pg in m['pages']:
        for it in pg['items']:
            if it['type'] != 'table' or not it['rows']:
                continue
            rows = it['rows']
            n = max(len(r) for r in rows)
            rows = [r + [''] * (n - len(r)) for r in rows]
            x0, y0, x1, y1 = it['bbox']
            key = (n, round(x0 / 20), round(x1 / 20))
            first = ' '.join(rows[0])
            head = sum(1 for k in HDR_KW if k in first) >= 2
            if head:
                last[key] = (pg['page'], [list(r) for r in rows[:3]])
            elif key in last and pg['page'] - last[key][0] <= 3:
                rows = [list(h) for h in last[key][1]] + rows
            rows = [[c.replace('\n', ' ').strip() for c in r] for r in rows]
            ded = []
            for r in rows:
                if ded and r == ded[-1]:
                    continue
                ded.append(r)
            it['rows'] = ded  # DEDUPE_MARK


FIX = [('ProbeqPCR', 'Probe qPCR'), ('FastAmpliPremix', 'FastAmpli Premix'),
       ('Prime-ProbeMix', 'Prime-Probe Mix'), ('TemplateDNA', 'Template DNA'),
       ('ddH O 2', 'ddH2O'), ('UNG Ⅳ(Probe', 'UNG Ⅳ (Probe')]


def esc(s):
    s = s or ''
    for a, b in FIX:
        s = s.replace(a, b)
    return s.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;')


def build(toc_pages=None):
    parts = ['''<!DOCTYPE html><html lang="zh-CN"><head><meta charset="utf-8">
<style>
@page{size:A4;margin:24mm 22mm 22mm 22mm}
*{box-sizing:border-box}
body{font-family:"Times New Roman","Songti SC","SimSun",serif;font-size:12pt;line-height:1.75;color:#111;margin:0}
.cover{page-break-after:always;text-align:center;padding-top:55mm}
.cover .co{font-size:22pt;font-weight:700;color:#0d47a1}
.cover .ti{font-size:22pt;font-weight:700;margin-top:10mm}
.cover .sub{font-size:16pt;margin-top:6mm}
.cover .meta{font-size:12pt;color:#444;margin-top:38mm}
.toc{page-break-after:always}
.toc h2{font-size:16pt;margin:0 0 6mm 0}
.toc .row{font-size:12pt;display:flex;justify-content:space-between;border-bottom:1px dotted #bbb;padding:1.05mm 0}
.toc .row.l2{font-size:10.5pt;padding-left:8mm;color:#333}
.toc h2{margin-bottom:4mm}
h1{font-size:16pt;color:#12446e;margin:8mm 0 4mm;padding-bottom:2mm;border-bottom:1px solid #dfe8f2;page-break-after:avoid}
h2{font-size:16pt;color:#17364f;margin:6mm 0 3mm;page-break-after:avoid}
p{font-size:12pt;text-align:justify;text-indent:2em;margin:3mm 0}
p.cap{font-size:10.5pt;text-align:center;text-indent:0;color:#555;margin:2mm 0}
table{width:100%;border-collapse:collapse;font-size:10.5pt;margin:3mm 0;page-break-inside:auto}
th,td{border:1px solid #999;padding:1.8mm 2mm;vertical-align:middle}
tr{page-break-inside:avoid}
thead{display:table-header-group}
th{background:#edf3fa;font-weight:700}
td{font-weight:400}
figure{margin:4mm 0;text-align:center;page-break-inside:avoid}
img{max-width:62%;max-height:95mm}
</style></head><body>''']
    parts.append('''<div class="cover">
<div class="co">珠海宝锐生物科技有限公司</div>
<div class="ti">2×FastAmpli Premix-UNG Ⅳ（Probe qPCR）</div>
<div class="ti">产品稳定性研究资料</div>
<div class="sub">货号：M2181-4</div>
<div class="meta">文件编号：CA-10-04-R13-1.0<br>版本：1.0<br>整理日期：2026 年 10 月</div>
</div>''')

    # 目录
    toc = []
    models = {}
    for title, path, pref in CHAPTERS:
        if not os.path.exists(path):
            continue
        m = json.load(open(path, encoding='utf-8'))
        augment(m)
        models[pref] = m
        toc.append((title, 1))
        start = 1 if pref == 'main' else 0
        for pg in m['pages'][start:]:
            for it in pg['items']:
                if it['type'] == 'h' and len(it['text']) <= 40 and it['text'] not in [t[0] for t in toc]:
                    t2 = it['text'].strip()
                    if re.match(r'^\d+(\.\d+)?[\s、\.]', t2) and t2.count('.') <= 1:
                        toc.append((t2, 2))

    parts.append('<div class="toc"><h2>目  录</h2>')
    for i, (t, lv) in enumerate(toc):
        pn = toc_pages.get(str(i)) if toc_pages else ''
        parts.append(f'<div class="row{" l2" if lv==2 else ""}"><span>{esc(t)}</span><span>{pn}</span></div>')
    parts.append('</div>')

    idx = 0
    for title, path, pref in CHAPTERS:
        if pref not in models:
            continue
        parts.append(f'<h1 data-idx="{idx}">{esc(title)}</h1>'); idx += 1
        m = models[pref]
        start = 1 if pref == 'main' else 0
        for pg in m['pages'][start:]:
            for it in pg['items']:
                if it['type'] == 'h':
                    parts.append(f'<h2 data-idx="{idx}">{esc(it["text"])}</h2>'); idx += 1
                elif it['type'] == 'p':
                    cls = ' class="cap"' if (len(it['text']) <= 30 and it['text'][:1] in '表图') else ''
                    parts.append(f'<p{cls}>{esc(it["text"])}</p>')
                elif it['type'] == 'table':
                    rows = it['rows']
                    if not rows:
                        continue
                    parts.append('<table>')
                    parts.append('<thead><tr>' + ''.join(f'<th>{esc(c)}</th>' for c in rows[0]) + '</tr></thead><tbody>')
                    for r in rows[1:]:
                        parts.append('<tr>' + ''.join(f'<td>{esc(c)}</td>' for c in r) + '</tr>')
                    parts.append('</tbody></table>')
                elif it['type'] == 'img':
                    parts.append(f'<figure><img src="file://{it["path"]}"></figure>')
    parts.append('</body></html>')
    open(OUT_HTML, 'w', encoding='utf-8').write('\n'.join(parts))
    json.dump([[t, lv] for t, lv in toc], open('/tmp/toc.json', 'w', encoding='utf-8'), ensure_ascii=False)
    print('html →', OUT_HTML, '｜toc', len(toc))


if __name__ == '__main__':
    build(json.load(open('/tmp/toc_pages.json')) if os.path.exists('/tmp/toc_pages.json') else None)
