#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""归档：蛋白结构工作台 + 销售场景手册（文件 + 数据 + 脚本 + README）"""
import io
import os
import shutil
import time

W = '/Users/liuxinyuan/Desktop/Hermes输出-工作类'
ARC = W + '/归档/科研与蛋白工作台_2026-10-17'

DIRS = {
    '交付物': [W + '/销售分析/蛋白结构与性能工作台.html',
            W + '/销售分析/销售场景手册_PCR机理与Top5_2026-10-17.html',
            W + '/销售分析/蛋白结构图'],
    '数据': [W + '/数据/蛋白结构'],
    '脚本': [W + '/脚本/build_protein_data.py', W + '/脚本/render_proteins.py',
           W + '/脚本/render_overlay.py', W + '/脚本/render_mmlv_af.py',
           W + '/脚本/build_protein_workbench.py', W + '/脚本/build_protein_workbench_v2.py',
           W + '/脚本/add_sales_tab.py', W + '/脚本/build_sales_handbook.py',
           W + '/脚本/install_pymol.sh', W + '/脚本/pml'],
}

os.makedirs(ARC, exist_ok=True)
manifest = []
for sub, items in DIRS.items():
    dst_dir = os.path.join(ARC, sub)
    os.makedirs(dst_dir, exist_ok=True)
    for it in items:
        if not os.path.exists(it):
            print('跳过（不存在）:', it)
            continue
        dst = os.path.join(dst_dir, os.path.basename(it.rstrip('/')))
        if os.path.isdir(it):
            if os.path.exists(dst):
                shutil.rmtree(dst)
            shutil.copytree(it, dst)
            n = sum(len(f) for _, _, f in os.walk(dst))
            sz = sum(os.path.getsize(os.path.join(r, f)) for r, _, fs in os.walk(dst) for f in fs)
            manifest.append((sub + '/' + os.path.basename(it) + '/', '%d 个文件' % n, sz))
        else:
            shutil.copy2(it, dst)
            manifest.append((sub + '/' + os.path.basename(it), '1 个文件', os.path.getsize(dst)))
        print('✔', sub, os.path.basename(it))

total = sum(m[2] for m in manifest)
lines = ['# 科研与蛋白工作台 · 归档', '',
         '归档日期：2026-10-17', '来源目录：`~/Desktop/Hermes输出-工作类/`', '',
         '## 一、交付物', '',
         '| 文件 | 说明 |', '|---|---|',
         '| `交付物/蛋白结构与性能工作台.html` | 4 个蛋白（Taq/Tth/MMLV/UNG），内嵌 3Dmol，可旋转/缩放/按残基定位；结构域着色；10 条 PMID 关联 |',
         '| `交付物/销售场景手册_PCR机理与Top5_2026-10-17.html` | 独立自包含 45 KB：PCR 机理 + Top5 场景卡 + 对话演练 + 自测 10 题 |',
         '| `交付物/蛋白结构图/*.png` | PyMOL 渲染图（Taq/Tth/MMLV/UNG） |', '',
         '## 二、数据（可复现）', '',
         '- UniProt：P19821 / P52028 / P03355 / P12295（序列、结构域、活性位点）',
         '- 实验结构：1TAQ / 8XK9 / 4MH8 / 3UF7',
         '- 预测模型：AlphaFold（MMLV 661–1331 pLDDT 87.65；Tth 1–834 pLDDT 91.56）',
         '- 文献：`数据/蛋白结构/_pmid_abstracts.json`（12 篇摘要）', '',
         '## 三、重建步骤', '',
         '```bash',
         'python3 脚本/build_protein_data.py      # 抓 UniProt + PDB 列表',
         'python3 脚本/render_proteins.py         # PyMOL 出图（实验结构）',
         'python3 脚本/render_overlay.py Tth P52028 8XK9_conv.pdb   # 预测+实验叠加',
         'python3 脚本/build_protein_workbench_v2.py   # 生成 3D 工作台',
         'python3 脚本/build_sales_handbook.py    # 生成销售场景手册',
         '```', '',
         '## 四、必须知道的限制', '',
         '1. Tth 的 5′→3′ 外切域在实验结构中无序，1–295 为 AlphaFold 预测；',
         '2. MMLV 的 RNase H 域为预测，4MH8 只覆盖到 487 位；',
         '3. 结构域边界为文献近似，不同文献略有差异；',
         '4. 销售场景频次来自宝锐活动/客诉记录，不是行业报告。', '',
         '## 五、文件清单', '', '| 路径 | 数量 | 大小 |', '|---|---|---|']
for m in manifest:
    lines.append('| `%s` | %s | %.0f KB |' % (m[0], m[1], m[2] / 1024))
lines += ['', '**合计 %.1f MB**' % (total / 1024 / 1024), '']
io.open(os.path.join(ARC, 'README.md'), 'w', encoding='utf-8').write('\n'.join(lines))
print('\n✅ 归档完成：%s ｜ %.1f MB' % (ARC, total / 1024 / 1024))
