#!/usr/bin/env python3
"""
宇之然内容创作流水线（研究 → 大纲 → 撰写 → 合规优化）v2
"""

import json, datetime, logging, sys, subprocess
from pathlib import Path
from typing import Dict

PROJECT_ROOT = Path('/root/.openclaw/workspaces/yzr-yxl/projects/yu-zhi-ran')
sys.path.insert(0, str(PROJECT_ROOT))

DATA_DIR = PROJECT_ROOT / "automation" / "data"
TOPICS_FILE = DATA_DIR / "sustainability_topics.json"
LOGS_DIR = PROJECT_ROOT / "automation" / "logs"
TODAY = datetime.datetime.now().strftime("%Y-%m-%d")

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler(LOGS_DIR / f"creator_{TODAY}.log"),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

def select_next_topic(topic_id: str = None) -> Dict:
    """选择并锁定要创作的选题"""
    def save_topics(topics_list):
        with open(TOPICS_FILE, 'w', encoding='utf-8') as f:
            json.dump(topics_list, f, ensure_ascii=False, indent=2)
    
    topics = json.loads(TOPICS_FILE.read_text(encoding='utf-8'))
    
    if topic_id:
        # 指定ID，尝试直接锁定
        topic = next((t for t in topics if t['id'] == topic_id), None)
        if not topic:
            raise ValueError(f"Topic {topic_id} not found")
        # 检查状态
        if topic.get('status') != 'pending' and topic.get('status') != '待处理':
            raise ValueError(f"Topic {topic_id} status is {topic.get('status')}, cannot create")
        # 加锁
        topic['lock_by'] = 'creator'
        topic['lock_at'] = datetime.datetime.now().isoformat()
        save_topics(topics)
        return topic
    
    # 自动选择：优先选pending且无锁的
    def is_available(t):
        status = t.get('status')
        # 只处理 pending 或 待处理
        if status not in ['pending', '待处理']:
            return False
        # 检查锁
        lock_by = t.get('lock_by')
        if lock_by:
            # 如果有人锁了，检查是否超时（>2小时）
            lock_at_str = t.get('lock_at')
            if lock_at_str:
                try:
                    lock_at = datetime.datetime.fromisoformat(lock_at_str)
                    if (datetime.datetime.now() - lock_at).total_seconds() < 7200:
                        return False
                except:
                    pass  # 解析失败，认为是有效锁
            else:
                return False
        return True
    
    available = [t for t in topics if is_available(t)]
    if not available:
        raise ValueError("No available topics to create (all locked or wrong status)")
    
    available.sort(key=lambda t: t.get('priority_score', 0), reverse=True)
    chosen = available[0]
    
    # 锁定
    chosen['lock_by'] = 'creator'
    chosen['lock_at'] = datetime.datetime.now().isoformat()
    save_topics(topics)
    
    return chosen

def run_step(script_name: str, topic_id: str) -> bool:
    """运行一个流水线步骤（research/outline/writer）"""
    script_path = PROJECT_ROOT / "scripts" / script_name
    cmd = ["python3", str(script_path), "--topic-id", topic_id]
    logger.info(f"Running: {' '.join(cmd)}")
    result = subprocess.run(cmd, cwd=str(PROJECT_ROOT), capture_output=True, text=True, timeout=300)
    if result.returncode != 0:
        logger.error(f"{script_name} 失败: {result.stderr}")
        return False
    logger.info(f"{script_name} 完成: {result.stdout.strip()}")
    return True

def run_optimizer_step(topic_id: str) -> bool:
    """运行合规优化步骤（只针对单个选题）"""
    script_path = PROJECT_ROOT / "scripts" / "compliance_optimizer.py"
    cmd = ["python3", str(script_path), "--topic-ids", topic_id]
    logger.info(f"Running: {' '.join(cmd)}")
    result = subprocess.run(cmd, cwd=str(PROJECT_ROOT), capture_output=True, text=True, timeout=600)
    if result.returncode != 0:
        logger.error(f"compliance_optimizer 失败: {result.stderr}")
        return False
    logger.info(f"compliance_optimizer 完成: {result.stdout.strip()}")
    return True

def run_pipeline(topic_id: str = None) -> Dict:
    """运行完整流水线：研究 → 大纲 → 撰写 → 合规优化"""
    tid = None
    try:
        topic = select_next_topic(topic_id)
        tid = topic['id']
        logger.info(f"开始创作流水线: topic_id={tid}, title={topic.get('title')}")

        # 1. 研究
        if not run_step("research.py", tid):
            return {"ok": False, "error": "research step failed"}

        # 2. 大纲
        if not run_step("outline.py", tid):
            return {"ok": False, "error": "outline step failed"}

        # 3. 撰写
        if not run_step("writer.py", tid):
            return {"ok": False, "error": "writer step failed"}

        # 4. 合规优化（自动审核并标记为「待发布」）
        if not run_optimizer_step(tid):
            return {"ok": False, "error": "optimizer step failed"}

        logger.info(f"创作流水线完成: topic_id={tid}")
        return {"ok": True, "topic_id": tid, "stdout": f"SUCCESS: Topic {tid} processed through full pipeline"}
    except Exception as e:
        logger.exception("流水线执行失败")
        return {"ok": False, "error": str(e)}
    finally:
        # 清理锁（无论成功失败）
        if tid:
            try:
                topics = json.loads(TOPICS_FILE.read_text(encoding='utf-8'))
                for t in topics:
                    if t.get('id') == tid:
                        # 如果成功或需要人工，保留状态，但清除锁
                        t['lock_by'] = None
                        t['lock_at'] = None
                        break
                with open(TOPICS_FILE, 'w', encoding='utf-8') as f:
                    json.dump(topics, f, ensure_ascii=False, indent=2)
                logger.debug(f"已清理选题锁: {tid}")
            except Exception as ex:
                logger.error(f"清理锁失败: {ex}")

def main():
    import argparse
    parser = argparse.ArgumentParser(description='内容创作流水线（研究→大纲→撰写→合规优化）')
    parser.add_argument('--topic-id', help='指定选题ID，不指定则自动选择待处理选题')
    args = parser.parse_args()

    result = run_pipeline(args.topic_id)
    print(json.dumps(result, ensure_ascii=False))
    sys.exit(0 if result['ok'] else 1)

if __name__ == "__main__":
    main()
