#!/usr/bin/env python3
from pathlib import Path
import html
import re

ROOT = Path(__file__).resolve().parents[1]
SRC = ROOT / '财务系统需求汇总.md'
OUT = ROOT / '财务系统需求汇总.html'

text = SRC.read_text(encoding='utf-8')
# The public-facing HTML keeps the requirements and pending questions, but omits the internal update log.
text = re.sub(r'\n---\n\n## 更新记录[\s\S]*$', '', text).strip()


def inline(s: str) -> str:
    s = html.escape(s)
    s = re.sub(r'`([^`]+)`', r'<code>\1</code>', s)
    s = re.sub(r'\*\*([^*]+)\*\*', r'<strong>\1</strong>', s)
    return s

body = []
toc = []
para = []
in_ul = False
in_ol = False
in_quote = False


def flush_para():
    if para:
        body.append('<p>' + '<br>'.join(inline(x) for x in para) + '</p>')
        para.clear()


def close_lists():
    global in_ul, in_ol, in_quote
    if in_ul:
        body.append('</ul>')
        in_ul = False
    if in_ol:
        body.append('</ol>')
        in_ol = False
    if in_quote:
        body.append('</blockquote>')
        in_quote = False


for raw in text.splitlines():
    line = raw.rstrip()
    if not line:
        flush_para(); close_lists(); continue
    if line.startswith('>'):
        flush_para()
        if not in_quote:
            if in_ul:
                body.append('</ul>'); in_ul = False
            if in_ol:
                body.append('</ol>'); in_ol = False
            body.append('<blockquote>'); in_quote = True
        body.append('<p>' + inline(line.lstrip('> ').strip()) + '</p>')
        continue
    m = re.match(r'^(#{1,4})\s+(.*)$', line)
    if m:
        flush_para(); close_lists()
        level = len(m.group(1)); title = m.group(2).strip()
        slug = re.sub(r'[^\w\u4e00-\u9fff-]+', '-', title).strip('-') or 'section'
        if level in (2, 3):
            cls = 'sub' if level == 3 else 'main'
            toc.append(f'<a class="toc-{cls}" href="#{html.escape(slug)}">{inline(title)}</a>')
        body.append(f'<h{level} id="{html.escape(slug)}">{inline(title)}</h{level}>')
        continue
    m = re.match(r'^\s*-\s+(.*)$', line)
    if m:
        flush_para()
        if in_ol:
            body.append('</ol>'); in_ol = False
        if in_quote:
            body.append('</blockquote>'); in_quote = False
        if not in_ul:
            body.append('<ul>'); in_ul = True
        body.append('<li>' + inline(m.group(1).strip()) + '</li>')
        continue
    m = re.match(r'^\s*\d+[\.、]\s+(.*)$', line)
    if m:
        flush_para()
        if in_ul:
            body.append('</ul>'); in_ul = False
        if in_quote:
            body.append('</blockquote>'); in_quote = False
        if not in_ol:
            body.append('<ol>'); in_ol = True
        body.append('<li>' + inline(m.group(1).strip()) + '</li>')
        continue
    flush_para(); close_lists(); para.append(line)
flush_para(); close_lists()

css = r'''
:root{--paper:#fff;--ink:#1f2937;--line:#e6eaf0;--blue:#2563eb;--shadow:0 18px 50px rgba(20,35,70,.08)}
*{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;background:linear-gradient(180deg,#eef4ff 0%,#f7f8fb 260px,#f5f7fb 100%);color:var(--ink);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei",Arial,sans-serif;line-height:1.72}.page{max-width:1180px;margin:0 auto;padding:34px 22px 80px}.hero{background:var(--paper);border:1px solid var(--line);box-shadow:var(--shadow);border-radius:28px;padding:36px 40px;margin-bottom:22px;position:relative;overflow:hidden}.hero:after{content:"";position:absolute;right:-90px;top:-120px;width:330px;height:330px;background:radial-gradient(circle,rgba(37,99,235,.16),rgba(37,99,235,0) 68%)}h1{font-size:36px;letter-spacing:-.02em;margin:0 0 12px;font-weight:800;color:#111827}.tagline{max-width:760px;color:#475467;font-size:16px}.meta{display:flex;gap:10px;flex-wrap:wrap;margin-top:18px}.pill{font-size:13px;color:#174ea6;background:#eaf2ff;border:1px solid #d7e7ff;padding:6px 12px;border-radius:999px}.layout{display:grid;grid-template-columns:270px 1fr;gap:22px}.toc{position:sticky;top:18px;align-self:start;background:rgba(255,255,255,.92);backdrop-filter:blur(12px);border:1px solid var(--line);border-radius:22px;padding:18px;box-shadow:0 8px 28px rgba(20,35,70,.06);max-height:calc(100vh - 36px);overflow:auto}.toc-title{font-weight:800;margin-bottom:10px;color:#111827}.toc a{display:block;text-decoration:none;color:#344054;border-radius:10px;padding:7px 9px;margin:2px 0;font-size:13px}.toc a:hover{background:#eef4ff;color:var(--blue)}.toc-sub{padding-left:20px!important;color:#667085!important;font-size:12px!important}.content{background:var(--paper);border:1px solid var(--line);border-radius:28px;padding:34px 42px;box-shadow:var(--shadow)}h2{margin:42px 0 16px;padding-top:18px;border-top:1px solid var(--line);font-size:25px;color:#111827}h2:first-child{margin-top:0;border-top:0;padding-top:0}h3{margin:26px 0 10px;font-size:19px;color:#174ea6}p{margin:10px 0;color:#344054}blockquote{margin:16px 0;padding:14px 18px;background:#f0f7ff;border-left:4px solid var(--blue);border-radius:14px;color:#24476f}ul,ol{margin:10px 0 16px;padding-left:23px}li{margin:5px 0}.content>ul,.content>ol{background:#fbfcff;border:1px solid #edf1f7;border-radius:16px;padding:14px 20px 14px 34px}.footer{font-size:12px;color:#98a2b3;text-align:center;margin-top:28px}.print-btn{position:fixed;right:22px;bottom:22px;border:0;background:#2563eb;color:white;border-radius:999px;padding:12px 18px;font-weight:700;box-shadow:0 12px 28px rgba(37,99,235,.28);cursor:pointer;z-index:20}@media(max-width:900px){.layout{grid-template-columns:1fr}.toc{position:relative;top:0}.hero,.content{padding:26px 22px}h1{font-size:28px}.print-btn{display:none}}@media print{body{background:white}.page{max-width:none;padding:0}.toc,.print-btn{display:none}.hero,.content{box-shadow:none;border:0;border-radius:0}.content{padding:0}a{color:inherit}}
'''

doc = f'''<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>财务系统需求汇总</title><style>{css}</style></head><body><button class="print-btn" onclick="window.print()">打印 / 另存PDF</button><main class="page"><section class="hero"><h1>财务系统需求汇总</h1><div class="tagline">围绕财务总览、报销审批、个人账、公共账、应收应付与合同台账的功能需求整理。当前版本用于沟通开发范围、确认实现优先级和后续补充。</div><div class="meta"><span class="pill">持续更新版</span><span class="pill">按模块归类</span><span class="pill">含待确认事项</span></div></section><section class="layout"><nav class="toc"><div class="toc-title">目录</div>{''.join(toc)}</nav><article class="content">{''.join(body)}</article></section><div class="footer">财务系统需求汇总 · HTML 分享版</div></main></body></html>'''
OUT.write_text(doc, encoding='utf-8')
print(OUT)
print(OUT.stat().st_size)
