#!/usr/bin/env python3
"""
WordPress 文章发布脚本 (REST API)
发布到 https://dianziqianzhang.com

⚠️ 注意：WordPress REST API 需要 cookie + nonce 认证（Basic Auth 无效）。
每次发布前需要先登录获取 cookie 和 REST API nonce。

用法:
  python3 publish-wordpress-rest.py <markdown_file> [--status draft|publish] [--categories 1,2,3]

参数:
  markdown_file  - 要发布的 Markdown 文件路径
  --status       - 发布状态: draft(草稿) / publish(发布), 默认 draft
  --categories   - 分类 ID 列表, 逗号分隔
  --tags         - 标签名列表, 逗号分隔
"""

import argparse
import os
import sys
import re
import requests
import html as html_mod

# WordPress 站点配置
WP_DOMAIN = "www.dianziqianzhang.com"
WP_BASE = "https://www.dianziqianzhang.com"
WP_USERNAME = "admin"
WP_PASSWORD = "VCLxs8476YWM"
WP_API_BASE = f"{WP_BASE}/wp-json/wp/v2"


def login_and_get_nonce():
    """登录 WordPress 并获取 cookie 和 REST API nonce"""
    session = requests.Session()
    
    # 步骤1: 登录获取 cookie
    login_url = f"{WP_BASE}/wp-login.php"
    login_data = {
        "log": WP_USERNAME,
        "pwd": WP_PASSWORD,
        "wp-submit": "Log In",
        "redirect_to": "/wp-admin/",
        "testcookie": "1"
    }
    
    resp = session.post(login_url, data=login_data)
    if "login_error" in resp.text or "错误" in resp.text:
        print("❌ 登录失败")
        sys.exit(1)
    
    # 步骤2: 从 post-new.php 页面获取 REST API nonce
    # ⚡ 关键: 必须从 wpApiSettings 中提取 nonce, 而不是页面中的其他 nonce
    post_new_url = f"{WP_BASE}/wp-admin/post-new.php"
    resp = session.get(post_new_url)
    
    # 提取 wpApiSettings 中的 nonce
    match = re.search(r'wpApiSettings\s*=\s*\{[^}]*?"nonce"\s*:\s*"([^"]+)"', resp.text)
    if not match:
        print("❌ 无法获取 REST API nonce")
        sys.exit(1)
    
    nonce = match.group(1)
    print(f"✅ 登录成功，nonce: {nonce[:8]}...")
    
    return session, nonce


def markdown_to_html(md_content):
    """简单的 markdown 转 HTML"""
    title = ""
    body = md_content
    
    # 提取第一个 # 标题
    title_match = re.search(r'^#\s+(.+)$', md_content, re.MULTILINE)
    if title_match:
        title = title_match.group(1).strip()
    
    # 处理代码块
    html = re.sub(r'```(\w*)\n(.*?)```', r'<pre><code>\2</code></pre>', md_content, flags=re.DOTALL)
    # 图片
    html = re.sub(r'!\[(.*?)\]\((.*?)\)', r'<img src="\2" alt="\1" style="max-width:100%">', html)
    # 链接
    html = re.sub(r'\[(.*?)\]\((.*?)\)', r'<a href="\2">\1</a>', html)
    # 粗斜体
    html = re.sub(r'\*\*\*(.+?)\*\*\*', r'<strong><em>\1</em></strong>', html)
    html = re.sub(r'\*\*(.+?)\*\*', r'<strong>\1</strong>', html)
    html = re.sub(r'\*(.+?)\*', r'<em>\1</em>', html)
    # 标题
    html = re.sub(r'^###\s+(.+)$', r'<h3>\1</h3>', html, flags=re.MULTILINE)
    html = re.sub(r'^##\s+(.+)$', r'<h2>\1</h2>', html, flags=re.MULTILINE)
    html = re.sub(r'^#\s+(.+)$', r'<h1>\1</h1>', html, flags=re.MULTILINE)
    # 列表
    html = re.sub(r'^\s*[-*]\s+(.+)$', r'<li>\1</li>', html, flags=re.MULTILINE)
    html = re.sub(r'(<li>.*?</li>)(\s*<li>)', r'\1\2', html, flags=re.DOTALL)
    html = re.sub(r'(<li>.*?</li>)\s*(?:\n\n|$)', r'<ul>\1</ul>\n\n', html, flags=re.DOTALL)
    # 引用
    html = re.sub(r'^>\s+(.+)$', r'<blockquote>\1</blockquote>', html, flags=re.MULTILINE)
    # 段落
    html = re.sub(r'\n\n+', '</p><p>', html)
    html = '<p>' + html + '</p>'
    
    return title, html


def get_categories(session, nonce):
    """获取所有分类"""
    resp = session.get(f"{WP_API_BASE}/categories?per_page=50",
                       headers={"X-WP-Nonce": nonce})
    if resp.status_code == 200:
        return {c["id"]: c["name"] for c in resp.json()}
    return {}


def create_category(session, nonce, name):
    """创建新分类"""
    resp = session.post(f"{WP_API_BASE}/categories",
                        headers={"X-WP-Nonce": nonce},
                        json={"name": name})
    if resp.status_code in (200, 201):
        return resp.json()["id"]
    return None


def publish(args):
    """主发布函数"""
    if not os.path.exists(args.markdown_file):
        print(f"❌ 文件不存在: {args.markdown_file}")
        sys.exit(1)
    
    # 读取文章
    with open(args.markdown_file, 'r', encoding='utf-8') as f:
        md_content = f.read()
    
    # 转换 Markdown 为 HTML
    title, html_content = markdown_to_html(md_content)
    
    if not title:
        title = os.path.splitext(os.path.basename(args.markdown_file))[0]
    
    print(f"📄 标题: {title}")
    
    # 登录获取认证
    print("🔑 登录中...")
    session, nonce = login_and_get_nonce()
    
    # 处理分类
    category_ids = []
    if args.categories:
        category_ids = [int(c.strip()) for c in args.categories.split(",") if c.strip()]
    
    # 构建请求
    post_data = {
        "title": title,
        "content": html_content,
        "status": args.status,
        "categories": category_ids
    }
    
    # 发布
    print(f"📤 正在发布 ({args.status})...")
    resp = session.post(f"{WP_API_BASE}/posts",
                        headers={
                            "X-WP-Nonce": nonce,
                            "Content-Type": "application/json"
                        },
                        json=post_data)
    
    if resp.status_code in (200, 201):
        result = resp.json()
        status_text = "已发布" if args.status == "publish" else "草稿"
        post_url = f"{WP_BASE}/?p={result['id']}"
        print(f"✅ 文章「{title}」{status_text}成功！")
        print(f"📎 文章ID: {result['id']}")
        print(f"🔗 链接: {post_url}")
        return {"success": True, "post_id": result["id"], "title": title}
    else:
        error = resp.json()
        print(f"❌ 发布失败: {error.get('message', '未知错误')}")
        return {"success": False, "error": error}


def main():
    parser = argparse.ArgumentParser(description='通过 REST API 发布文章到电子签章网')
    parser.add_argument('markdown_file', help='Markdown 文章文件路径')
    parser.add_argument('--status', choices=['draft', 'publish'], default='draft')
    parser.add_argument('--categories', help='分类 ID，逗号分隔')
    parser.add_argument('--tags', help='标签名，逗号分隔')
    
    args = parser.parse_args()
    result = publish(args)
    
    if not result.get('success'):
        sys.exit(1)


if __name__ == '__main__':
    main()
