#!/usr/bin/env python3
"""
撰写阶段：基于大纲和选题生成完整文章（三平台版本）- 数据库版
"""

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

PROJECT_ROOT = Path(__file__).parent.parent
# 添加项目根和 backend 路径，以导入 app.core.llm_client
sys.path.insert(0, str(PROJECT_ROOT))
sys.path.insert(0, str(PROJECT_ROOT / 'platform' / 'backend'))

# 导入 LLM 客户端（NVIDIA）
from app.database import SessionLocal
from app.models import Topic
try:
    from app.core.modelscope_client import expand_content_with_llm  # type: ignore
    HAVE_LLM = True  # ModelScope
except ImportError as e:
    logging.warning(f"LLM client unavailable: {e}")
    HAVE_LLM = False

# 导入数据库辅助模块
from db_helper import get_topic_by_id, update_topic_status

PROJECT_ROOT = Path(__file__).parent.parent
sys.path.insert(0, str(PROJECT_ROOT))

DATA_DIR = PROJECT_ROOT / "automation" / "data"
OUTLINE_DIR = DATA_DIR / "outlines"
RELEASE_DIR = DATA_DIR / "releases"
TEMPLATES_DIR = PROJECT_ROOT / "automation" / "templates"
LOGS_DIR = PROJECT_ROOT / "automation" / "logs"
TODAY = datetime.datetime.now().strftime("%Y-%m-%d")
GEN_TIME = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

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

class Writer:
    def __init__(self, topic_id: str):
        self.topic_id = topic_id
        self.topic = self._load_topic()
        outline_file = OUTLINE_DIR / TODAY / f"{topic_id}_outline.md"
        if not outline_file.exists():
            raise FileNotFoundError(f"Outline not found: {outline_file}")
        self.outline_content = outline_file.read_text(encoding='utf-8')
        self.release_dir = RELEASE_DIR / TODAY
        self.release_dir.mkdir(parents=True, exist_ok=True)
        # 加载研究笔记（作为 LLM 上下文）
        research_file = DATA_DIR / "research" / TODAY / f"{topic_id}_research.md"
        self.research_notes = research_file.read_text(encoding='utf-8') if research_file.exists() else ""

    def _load_topic(self) -> Dict:
        topic = get_topic_by_id(self.topic_id)
        if not topic:
            raise ValueError(f"Topic {self.topic_id} not found")
        return topic

    def _clean_title(self, title: str) -> str:
        """去除标题中的指导性文字（如字数说明、MVP标记等）"""
        import re
        # 去掉括号中的说明：约200字、约300字、MVP、试行等
        title = re.sub(r'[（(]约\s*\d+字[）)]', '', title)
        title = re.sub(r'[（(]MVP[）)]', '', title)
        title = re.sub(r'[（(][^）)]*?[）)]', '', title)  # 保守移除任意括号内容（可能误伤，但大纲通常不包含重要括号信息）
        return title.strip()

    def _parse_outline_sections(self) -> List[Dict]:
        """将大纲 Markdown 解析为结构化列表，保留层级和内容"""
        sections = []
        current = None
        for line in self.outline_content.splitlines():
            if line.startswith("# "):
                if current:
                    sections.append(current)
                current = {"level": 1, "title": line[2:].strip(), "content": ""}
            elif line.startswith("## "):
                if current:
                    sections.append(current)
                current = {"level": 2, "title": line[3:].strip(), "content": ""}
            elif line.startswith("### "):
                if current:
                    sections.append(current)
                current = {"level": 3, "title": line[4:].strip(), "content": ""}
            else:
                if current and line.strip():
                    current['content'] = current.get('content', '') + line + "\n"
        if current:
            sections.append(current)
        return sections

    def _expand_section(self, section: Dict) -> str:
        """将大纲中的简短描述扩展为完整段落"""
        content = section.get('content', '').strip()
        # 如果有足够内容（>200字），直接返回
        if len(content) > 200:
            return content
        # 如果内容极少，需要 LLM 扩写
        if HAVE_LLM and len(content) < 150:
            logger.info(f"使用 LLM 扩写章节: {section['title']}")
            try:
                expanded = expand_content_with_llm(
                    topic=self.topic,
                    section_title=section['title'],
                    section_content=content,
                    context=self.research_notes
                )
                if expanded and len(expanded.strip()) > len(content):
                    return expanded.strip()
                else:
                    logger.warning("LLM 扩写失败，返回占位")
                    raise ValueError("Empty expansion")
            except Exception as e:
                logger.warning(f"LLM 扩写失败: {e}，使用占位内容")
                # 返回占位内容，保持流程继续
                return f"{content}\n\n（本段内容需要人工补充：当前模型调用失败或未配置）"
        # 否则返回原内容
        return content

    def generate_full_markdown(self) -> str:
        """根据大纲生成完整 Markdown 正文"""
        sections = self._parse_outline_sections()
        parts = []

        for sec in sections:
            if sec.get('content'):
                expanded = self._expand_section(sec)
                parts.append(expanded + "\n\n")

        full_md = "\n".join(parts).strip()
        return full_md

    def generate_platform_html(self, markdown: str, platform: str) -> str:
        """将 Markdown 转换为平台 HTML（基于模板）"""
        title = self.topic['title']

        # 加载模板
        tpl_path = TEMPLATES_DIR / f"{platform}.html"
        if tpl_path.exists():
            template = tpl_path.read_text(encoding='utf-8')
        else:
            template = "<!DOCTYPE html><html><head><meta charset='UTF-8'><title>{{TITLE}}</title></head><body><h1>{{TITLE}}</h1><!-- CONTENT --></body></html>"

        # 替换变量
        html = template.replace("{{TITLE}}", title).replace("{{DATE}}", TODAY).replace("{{GEN_TIME}}", GEN_TIME)

        # 注入内容
        html_content = self._markdown_to_html(markdown)
        html = html.replace("<!-- CONTENT -->", html_content)

        # 平台特定标签补充
        if platform == "zhihu":
            tags = '<div class="tags">#科技 #职场</div>'
            html = html.replace("<!-- TAGS -->", tags)
        elif platform == "xiaohongshu":
            hashtags = '<div class="hashtags">#AI #可持续 #生活方式</div>'
            html = html.replace("<!-- HASHTAGS -->", hashtags)
        elif platform == "wechat":
            pass

        return html

    def _markdown_to_html(self, md: str) -> str:
        """极简 markdown 转换（仅本场景使用）"""
        lines = md.split('\n')
        html_parts = []
        for line in lines:
            if line.startswith('# '):
                html_parts.append(f"<h1>{line[2:]}</h1>")
            elif line.startswith('## '):
                html_parts.append(f"<h2>{line[3:]}</h2>")
            elif line.startswith('### '):
                html_parts.append(f"<h3>{line[4:]}</h3>")
            elif line.strip().startswith('- '):
                html_parts.append(f"<li>{line[2:]}</li>")
            elif re.match(r'^\d+\. ', line):
                content = re.sub(r'^\d+\. ', '', line)
                html_parts.append(f"<li>{content}</li>")
            elif line.strip():
                html_parts.append(f"<p>{line}</p>")
            else:
                html_parts.append("")
        return "\n".join(html_parts)

    def save_html(self, html: str, platform: str) -> Path:
        out_dir = self.release_dir / platform
        out_dir.mkdir(parents=True, exist_ok=True)
        filename = f"{platform}_{self.topic_id}_{platform}.html"
        out_path = out_dir / filename
        out_path.write_text(html, encoding='utf-8')
        logger.info(f"HTML 生成: {out_path}")
        return out_path

    def mark_draft(self):
        """标记选题为「待审查」"""
        # 更新数据库状态
        update_topic_status(self.topic_id, 'review')
        logger.info(f"选题 {self.topic_id} 状态已更新为待审查（数据库）")

    def run(self):
        logger.info("开始撰写阶段")
        markdown = self.generate_full_markdown()
        results = {}
        for platform in ["zhihu", "wechat", "xiaohongshu"]:
            html = self.generate_platform_html(markdown, platform)
            results[platform] = str(self.save_html(html, platform))
        self.mark_draft()
        logger.info(f"撰写完成，状态已更新为待审查")
        return {"ok": True, "files": results}

def main():
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('--topic-id', required=True, help='选题ID')
    args = parser.parse_args()

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

if __name__ == "__main__":
    main()
