from pathlib import Path
import html, re, shutil

ROOT = Path(__file__).parent
SITE = ROOT / "site"
DOCS = SITE / "docs"
SITE.mkdir(exist_ok=True)
DOCS.mkdir(exist_ok=True)

CSS = r'''
:root{--bg:#0c0d10;--panel:#15171c;--panel2:#1c1f26;--text:#f4f2ed;--muted:#a7a7ad;--line:#2c2f38;--accent:#f07c5f;--accent2:#ffd2a6;--code:#101116}*{box-sizing:border-box}body{margin:0;background:radial-gradient(circle at 85% -10%,#3c2019 0,transparent 33%),var(--bg);color:var(--text);font:16px/1.75 Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif}a{color:var(--accent2);text-decoration:none}a:hover{text-decoration:underline}.wrap{max-width:1120px;margin:auto;padding:0 24px}.nav{border-bottom:1px solid var(--line);padding:18px 0}.nav .wrap{display:flex;justify-content:space-between;align-items:center;gap:20px}.brand{font-weight:800;letter-spacing:.03em;color:var(--text)}.brand span{color:var(--accent)}.navlinks{display:flex;gap:18px;font-size:14px}.hero{padding:78px 0 50px;max-width:820px}.eyebrow{color:var(--accent);font-size:13px;font-weight:800;letter-spacing:.16em;text-transform:uppercase}.hero h1{font-size:clamp(38px,7vw,76px);line-height:1.04;letter-spacing:-.055em;margin:14px 0 22px}.hero p{color:var(--muted);font-size:19px;max-width:720px}.pill{display:inline-block;border:1px solid #6c4133;border-radius:999px;padding:4px 10px;color:var(--accent2);font-size:13px;margin:5px 5px 0 0}.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin:25px 0 65px}.card{background:linear-gradient(145deg,var(--panel),#111217);border:1px solid var(--line);border-radius:16px;padding:22px;min-height:170px}.card:hover{border-color:#85513e;transform:translateY(-2px);transition:.2s}.card h3{margin:4px 0 8px;font-size:19px;line-height:1.25}.card p{margin:0;color:var(--muted);font-size:14px}.section-title{font-size:13px;letter-spacing:.15em;text-transform:uppercase;color:var(--muted);margin:28px 0 12px}.doc{padding:48px 0 80px;max-width:860px}.doc h1{font-size:44px;line-height:1.12;letter-spacing:-.04em;margin:0 0 10px}.doc h2{font-size:28px;line-height:1.2;margin:42px 0 12px;border-top:1px solid var(--line);padding-top:22px}.doc h3{font-size:21px;margin:28px 0 8px}.doc p,.doc li{color:#dedde0}.doc blockquote{border-left:3px solid var(--accent);padding:8px 18px;margin:20px 0;background:#211816;color:var(--accent2)}.doc code{background:var(--code);border:1px solid var(--line);border-radius:5px;padding:1px 5px;color:#ffd9bd}.doc pre{overflow:auto;background:var(--code);border:1px solid var(--line);border-radius:10px;padding:16px;color:#e9e4dd}.meta{color:var(--muted);font-size:14px;margin-bottom:28px}.toc{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:14px 18px;margin:24px 0}.toc a{margin-right:14px;font-size:14px}.footer{border-top:1px solid var(--line);padding:28px 0 50px;color:var(--muted);font-size:13px}.back{font-size:14px;color:var(--muted)}.doc table{width:100%;border-collapse:collapse;margin:22px 0 30px;font-size:14px;display:block;overflow-x:auto;white-space:normal}.doc th,.doc td{border:1px solid var(--line);padding:11px 13px;text-align:left;vertical-align:top;min-width:120px}.doc th{background:var(--panel2);color:var(--accent2);font-weight:700}.doc tr:nth-child(even) td{background:rgba(255,255,255,.025)}.doc td code,.doc th code{white-space:nowrap}@media(max-width:800px){.grid{grid-template-columns:1fr 1fr}}@media(max-width:540px){.wrap{padding:0 17px}.grid{grid-template-columns:1fr}.hero{padding-top:54px}.navlinks{gap:10px}.doc h1{font-size:35px}}
'''


def inline(s):
    s = html.escape(s, quote=False)
    s = re.sub(r'`([^`]+)`', r'<code>\1</code>', s)
    s = re.sub(r'\[([^\]]+)\]\(([^)]+)\)', r'<a href="\2">\1</a>', s)
    s = re.sub(r'\*\*([^*]+)\*\*', r'<strong>\1</strong>', s)
    s = re.sub(r'\*([^*]+)\*', r'<em>\1</em>', s)
    return s


def markdown_to_html(text):
    lines = text.replace('\r\n','\n').split('\n')
    out=[]; i=0; in_ul=False; in_ol=False; in_code=False; code=[]
    def close_lists():
        nonlocal in_ul,in_ol
        if in_ul: out.append('</ul>'); in_ul=False
        if in_ol: out.append('</ol>'); in_ol=False
    while i < len(lines):
        line=lines[i]
        if line.startswith('```'):
            if not in_code:
                close_lists(); in_code=True; code=[]
            else:
                out.append('<pre><code>'+html.escape('\n'.join(code))+'</code></pre>'); in_code=False
            i+=1; continue
        if in_code:
            code.append(line); i+=1; continue
        if not line.strip():
            close_lists(); i+=1; continue
        if '|' in line and i+1 < len(lines) and re.match(r'^\s*\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)+\|?\s*$', lines[i+1]):
            close_lists()
            def cells(row):
                row=row.strip().strip('|')
                return [c.strip() for c in row.split('|')]
            headers=cells(line)
            i += 2
            rows=[]
            while i < len(lines) and '|' in lines[i] and lines[i].strip():
                rows.append(cells(lines[i])); i += 1
            out.append('<div class="table-wrap"><table><thead><tr>'+''.join('<th>'+inline(c)+'</th>' for c in headers)+'</tr></thead><tbody>')
            for row in rows:
                row=(row+['']*len(headers))[:len(headers)]
                out.append('<tr>'+''.join('<td>'+inline(c)+'</td>' for c in row)+'</tr>')
            out.append('</tbody></table></div>')
            continue
        m=re.match(r'^(#{1,3})\s+(.+)$',line)
        if m:
            close_lists(); level=len(m.group(1)); title=inline(m.group(2)); anchor=re.sub(r'[^a-z0-9]+','-',m.group(2).lower()).strip('-')
            out.append(f'<h{level} id="{anchor}">{title}</h{level}>'); i+=1; continue
        if line.startswith('> '):
            close_lists(); out.append('<blockquote>'+inline(line[2:])+'</blockquote>'); i+=1; continue
        m=re.match(r'^\s*[-*]\s+(.+)$',line)
        if m:
            if in_ol: out.append('</ol>'); in_ol=False
            if not in_ul: out.append('<ul>'); in_ul=True
            out.append('<li>'+inline(m.group(1))+'</li>'); i+=1; continue
        m=re.match(r'^\s*\d+\.\s+(.+)$',line)
        if m:
            if in_ul: out.append('</ul>'); in_ul=False
            if not in_ol: out.append('<ol>'); in_ol=True
            out.append('<li>'+inline(m.group(1))+'</li>'); i+=1; continue
        close_lists()
        para=[line]
        while i+1<len(lines) and lines[i+1].strip() and not re.match(r'^(#{1,3})\s|^\s*[-*]\s+|^\s*\d+\.\s+|^> |^```',lines[i+1]):
            i+=1; para.append(lines[i])
        out.append('<p>'+inline(' '.join(para))+'</p>'); i+=1
    if in_code: out.append('<pre><code>'+html.escape('\n'.join(code))+'</code></pre>')
    close_lists()
    return '\n'.join(out)


def page(title, body, active=''):
    return f'''<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="description" content="AI Agent 与 AI 项目开发方法文档集"><title>{html.escape(title)} · AI Agent Field Notes</title><style>{CSS}</style></head><body><header class="nav"><div class="wrap"><a class="brand" href="../index.html">AI <span>Agent</span> Field Notes</a><nav class="navlinks"><a href="../index.html">首页</a><a href="../docs/synthesis-agent-work-methodology.html">方法论</a><a href="../docs/synthesis-ai-project-development-recommendations.html">AI 项目</a><a href="../download.zip">下载 ZIP</a></nav></div></header>{body}<footer class="footer"><div class="wrap">资料整理于 2026-08-22 · 以原始来源链接为准 · <a href="../index.html">返回首页</a></div></footer></body></html>'''

# Copy assets
for name in ['openai-practical-guide.pdf']:
    src=ROOT/'sources'/name
    if src.exists(): shutil.copy2(src,SITE/name)

# Build each Markdown document
md_files=[]
for p in sorted(ROOT.rglob('*.md')):
    if 'site' in p.parts or p.name in ('README.md','METADATA.md'): continue
    rel=p.relative_to(ROOT)
    slug='-'.join(rel.with_suffix('').parts)
    out=DOCS/(slug+'.html')
    body='<main class="wrap doc"><a class="back" href="../index.html">← 返回文档集</a>'+markdown_to_html(p.read_text(encoding='utf-8'))+'</main>'
    out.write_text(page(p.stem.replace('-',' ').title(),body),encoding='utf-8')
    md_files.append((rel,slug+'.html'))

cards=[]
for rel, href in md_files:
    title=rel.stem.replace('-',' ').title()
    if 'agent-work-methodology' in href: desc='跨 Anthropic、OpenAI、Google、Microsoft、Cursor 等资料提炼的通用方法。'
    elif 'ai-project-development' in href: desc='从问题选择、MVP、数据、评估到上线的 AI 项目开发建议。'
    elif 'extended-agent-sources' in href: desc='16 条官方文档、工程文章与员工署名复盘的资料总表。'
    else: desc='原始资料的中文摘要、适用场景与可复用实践。'
    cards.append(f'<a class="card" href="docs/{href}"><div class="eyebrow">{html.escape(str(rel.parent))}</div><h3>{html.escape(title)}</h3><p>{desc}</p></a>')

body=f'''<main class="wrap"><section class="hero"><div class="eyebrow">FIELD NOTES · 2026</div><h1>把 AI Agent<br><span style="color:var(--accent)">做成真正可用的项目</span></h1><p>一套面向产品、研发和个人工作流的 AI Agent 与 AI 项目开发资料集：少一点概念，多一点可执行的任务边界、工具、评估、验证和上线方法。</p><span class="pill">Anthropic</span><span class="pill">OpenAI</span><span class="pill">Google</span><span class="pill">Microsoft</span><span class="pill">Cursor</span><span class="pill">Windsurf / Devin</span></section><div class="section-title">精选入口</div><section class="grid"><a class="card" href="docs/synthesis-agent-work-methodology.html"><div class="eyebrow">PLAYBOOK</div><h3>Agent 工作方法论</h3><p>什么时候不用 Agent，如何选择工作流、设计工具、管理上下文并建立验证闭环。</p></a><a class="card" href="docs/synthesis-ai-project-development-recommendations.html"><div class="eyebrow">BUILDING AI</div><h3>AI 项目开发建议</h3><p>从真实问题到 MVP，再到评估、成本、可靠性和生产部署。</p></a><a class="card" href="docs/sources-extended-agent-sources.html"><div class="eyebrow">SOURCE INDEX</div><h3>原始资料总表</h3><p>16 条官方文档、工程博客和员工署名的长文复盘，附链接与可靠性说明。</p></a></section><div class="section-title">全部文档</div><section class="grid">{''.join(cards)}</section></main>'''
(SITE/'index.html').write_text(page('首页',body),encoding='utf-8')
print(f'built {len(md_files)} documents into {SITE}')
