#!/usr/bin/env python3
"""
玉米期货投研PPT生成脚本
"""

from pptx import Presentation
from pptx.util import Inches, Pt, Cm
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.enum.shapes import MSO_SHAPE
import os

# 投研风格配色
COLORS = {
    'blue': RGBColor(26, 54, 93),      # 深蓝 #1a365d
    'gold': RGBColor(214, 158, 46),     # 金色 #d69e2e
    'red': RGBColor(197, 48, 48),       # 红色 #c53030
    'green': RGBColor(47, 133, 90),     # 绿色 #2f855a
    'white': RGBColor(255, 255, 255),
    'light_gray': RGBColor(247, 250, 252),
    'dark_gray': RGBColor(113, 128, 150),
}

def add_title_slide(prs, title, subtitle):
    """添加封面页"""
    slide = prs.slides.add_slide(prs.slide_layouts[6])  # 空白布局
    
    # 背景
    background = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0, prs.slide_width, prs.slide_height)
    background.fill.solid()
    background.fill.fore_color.rgb = COLORS['blue']
    background.line.fill.background()
    
    # 标题
    title_box = slide.shapes.add_textbox(Cm(1), Cm(6), prs.slide_width - Cm(2), Cm(3))
    tf = title_box.text_frame
    p = tf.paragraphs[0]
    p.text = title
    p.font.size = Pt(44)
    p.font.bold = True
    p.font.color.rgb = COLORS['white']
    p.alignment = PP_ALIGN.CENTER
    
    # 副标题
    subtitle_box = slide.shapes.add_textbox(Cm(1), Cm(9.5), prs.slide_width - Cm(2), Cm(1.5))
    tf = subtitle_box.text_frame
    p = tf.paragraphs[0]
    p.text = subtitle
    p.font.size = Pt(24)
    p.font.color.rgb = COLORS['gold']
    p.alignment = PP_ALIGN.CENTER
    
    # 底部信息
    footer_box = slide.shapes.add_textbox(Cm(1), Cm(15), prs.slide_width - Cm(2), Cm(1))
    tf = footer_box.text_frame
    p = tf.paragraphs[0]
    p.text = "方正中期期货研究院 | 2026年3月11日"
    p.font.size = Pt(14)
    p.font.color.rgb = COLORS['light_gray']
    p.alignment = PP_ALIGN.CENTER

def add_section_slide(prs, title):
    """添加章节页"""
    slide = prs.slides.add_slide(prs.slide_layouts[6])
    
    # 左侧色块
    left_bar = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0, Cm(0.8), prs.slide_height)
    left_bar.fill.solid()
    left_bar.fill.fore_color.rgb = COLORS['gold']
    left_bar.line.fill.background()
    
    # 标题
    title_box = slide.shapes.add_textbox(Cm(1.5), Cm(6), prs.slide_width - Cm(3), Cm(2))
    tf = title_box.text_frame
    p = tf.paragraphs[0]
    p.text = title
    p.font.size = Pt(36)
    p.font.bold = True
    p.font.color.rgb = COLORS['blue']
    p.alignment = PP_ALIGN.LEFT

def add_content_slide(prs, title, content_list):
    """添加内容页"""
    slide = prs.slides.add_slide(prs.slide_layouts[6])
    
    # 顶部色块
    top_bar = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0, prs.slide_width, Cm(1.2))
    top_bar.fill.solid()
    top_bar.fill.fore_color.rgb = COLORS['blue']
    top_bar.line.fill.background()
    
    # 标题
    title_box = slide.shapes.add_textbox(Cm(0.5), Cm(0.2), prs.slide_width - Cm(1), Cm(0.8))
    tf = title_box.text_frame
    p = tf.paragraphs[0]
    p.text = title
    p.font.size = Pt(24)
    p.font.bold = True
    p.font.color.rgb = COLORS['white']
    
    # 内容
    content_box = slide.shapes.add_textbox(Cm(0.8), Cm(1.8), prs.slide_width - Cm(1.6), Cm(12))
    tf = content_box.text_frame
    tf.word_wrap = True
    
    for i, item in enumerate(content_list):
        if i == 0:
            p = tf.paragraphs[0]
        else:
            p = tf.add_paragraph()
        p.text = f"• {item}"
        p.font.size = Pt(18)
        p.font.color.rgb = COLORS['blue']
        p.space_after = Pt(12)

def add_image_slide(prs, title, image_path, caption=""):
    """添加图片页"""
    slide = prs.slides.add_slide(prs.slide_layouts[6])
    
    # 顶部色块
    top_bar = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0, prs.slide_width, Cm(1.2))
    top_bar.fill.solid()
    top_bar.fill.fore_color.rgb = COLORS['blue']
    top_bar.line.fill.background()
    
    # 标题
    title_box = slide.shapes.add_textbox(Cm(0.5), Cm(0.2), prs.slide_width - Cm(1), Cm(0.8))
    tf = title_box.text_frame
    p = tf.paragraphs[0]
    p.text = title
    p.font.size = Pt(24)
    p.font.bold = True
    p.font.color.rgb = COLORS['white']
    
    # 图片
    if os.path.exists(image_path):
        slide.shapes.add_picture(image_path, Cm(0.8), Cm(1.8), width=prs.slide_width - Cm(1.6))
    
    # 说明
    if caption:
        caption_box = slide.shapes.add_textbox(Cm(0.8), Cm(13), prs.slide_width - Cm(1.6), Cm(1))
        tf = caption_box.text_frame
        p = tf.paragraphs[0]
        p.text = caption
        p.font.size = Pt(12)
        p.font.color.rgb = COLORS['dark_gray']
        p.alignment = PP_ALIGN.CENTER

def add_table_slide(prs, title, headers, data):
    """添加表格页"""
    slide = prs.slides.add_slide(prs.slide_layouts[6])
    
    # 顶部色块
    top_bar = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0, prs.slide_width, Cm(1.2))
    top_bar.fill.solid()
    top_bar.fill.fore_color.rgb = COLORS['blue']
    top_bar.line.fill.background()
    
    # 标题
    title_box = slide.shapes.add_textbox(Cm(0.5), Cm(0.2), prs.slide_width - Cm(1), Cm(0.8))
    tf = title_box.text_frame
    p = tf.paragraphs[0]
    p.text = title
    p.font.size = Pt(24)
    p.font.bold = True
    p.font.color.rgb = COLORS['white']
    
    # 表格
    rows = len(data) + 1
    cols = len(headers)
    table = slide.shapes.add_table(rows, cols, Cm(1), Cm(2), prs.slide_width - Cm(2), Cm(rows * 0.8)).table
    
    # 表头
    for i, header in enumerate(headers):
        cell = table.cell(0, i)
        cell.text = header
        cell.fill.solid()
        cell.fill.fore_color.rgb = COLORS['blue']
        p = cell.text_frame.paragraphs[0]
        p.font.color.rgb = COLORS['white']
        p.font.bold = True
        p.font.size = Pt(14)
    
    # 数据
    for row_idx, row_data in enumerate(data):
        for col_idx, cell_data in enumerate(row_data):
            cell = table.cell(row_idx + 1, col_idx)
            cell.text = str(cell_data)
            p = cell.text_frame.paragraphs[0]
            p.font.size = Pt(12)

def add_two_column_slide(prs, title, left_title, left_items, right_title, right_items):
    """添加双栏内容页"""
    slide = prs.slides.add_slide(prs.slide_layouts[6])
    
    # 顶部色块
    top_bar = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0, prs.slide_width, Cm(1.2))
    top_bar.fill.solid()
    top_bar.fill.fore_color.rgb = COLORS['blue']
    top_bar.line.fill.background()
    
    # 标题
    title_box = slide.shapes.add_textbox(Cm(0.5), Cm(0.2), prs.slide_width - Cm(1), Cm(0.8))
    tf = title_box.text_frame
    p = tf.paragraphs[0]
    p.text = title
    p.font.size = Pt(24)
    p.font.bold = True
    p.font.color.rgb = COLORS['white']
    
    # 左栏标题
    left_title_box = slide.shapes.add_textbox(Cm(0.8), Cm(1.8), Cm(10), Cm(0.8))
    tf = left_title_box.text_frame
    p = tf.paragraphs[0]
    p.text = left_title
    p.font.size = Pt(18)
    p.font.bold = True
    p.font.color.rgb = COLORS['green']
    
    # 左栏内容
    left_box = slide.shapes.add_textbox(Cm(0.8), Cm(2.8), Cm(10), Cm(10))
    tf = left_box.text_frame
    tf.word_wrap = True
    for i, item in enumerate(left_items):
        if i == 0:
            p = tf.paragraphs[0]
        else:
            p = tf.add_paragraph()
        p.text = f"✓ {item}"
        p.font.size = Pt(14)
        p.font.color.rgb = COLORS['blue']
        p.space_after = Pt(8)
    
    # 右栏标题
    right_title_box = slide.shapes.add_textbox(Cm(12), Cm(1.8), Cm(10), Cm(0.8))
    tf = right_title_box.text_frame
    p = tf.paragraphs[0]
    p.text = right_title
    p.font.size = Pt(18)
    p.font.bold = True
    p.font.color.rgb = COLORS['red']
    
    # 右栏内容
    right_box = slide.shapes.add_textbox(Cm(12), Cm(2.8), Cm(10), Cm(10))
    tf = right_box.text_frame
    tf.word_wrap = True
    for i, item in enumerate(right_items):
        if i == 0:
            p = tf.paragraphs[0]
        else:
            p = tf.add_paragraph()
        p.text = f"✗ {item}"
        p.font.size = Pt(14)
        p.font.color.rgb = COLORS['blue']
        p.space_after = Pt(8)

def add_footer_slide(prs):
    """添加封底"""
    slide = prs.slides.add_slide(prs.slide_layouts[6])
    
    # 背景
    background = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0, prs.slide_width, prs.slide_height)
    background.fill.solid()
    background.fill.fore_color.rgb = COLORS['blue']
    background.line.fill.background()
    
    # 感谢语
    thanks_box = slide.shapes.add_textbox(Cm(1), Cm(5), prs.slide_width - Cm(2), Cm(2))
    tf = thanks_box.text_frame
    p = tf.paragraphs[0]
    p.text = "感谢您的阅读"
    p.font.size = Pt(36)
    p.font.bold = True
    p.font.color.rgb = COLORS['white']
    p.alignment = PP_ALIGN.CENTER
    
    # 免责声明
    disclaimer_box = slide.shapes.add_textbox(Cm(1), Cm(9), prs.slide_width - Cm(2), Cm(3))
    tf = disclaimer_box.text_frame
    tf.word_wrap = True
    p = tf.paragraphs[0]
    p.text = "免责声明：本报告仅供参考，不构成投资建议。投资者据此操作，风险自担。"
    p.font.size = Pt(12)
    p.font.color.rgb = COLORS['light_gray']
    p.alignment = PP_ALIGN.CENTER
    
    # 联系方式
    contact_box = slide.shapes.add_textbox(Cm(1), Cm(13), prs.slide_width - Cm(2), Cm(2))
    tf = contact_box.text_frame
    p = tf.paragraphs[0]
    p.text = "方正中期期货研究院\n北京市西城区金融大街 | research@founder-futures.com"
    p.font.size = Pt(14)
    p.font.color.rgb = COLORS['gold']
    p.alignment = PP_ALIGN.CENTER

def main():
    # 创建PPT
    prs = Presentation()
    prs.slide_width = Cm(33.867)  # 16:9 宽屏
    prs.slide_height = Cm(19.05)
    
    image_dir = '/root/.openclaw/workspace/ppt_images'
    
    # 封面页
    add_title_slide(prs, "玉米期货行情研究报告", "C0主力合约分析 | 投资策略建议")
    
    # 目录页
    add_content_slide(prs, "目录", [
        "一、核心观点与投资建议",
        "二、行情回顾与量价分析",
        "三、基本面分析",
        "四、技术面分析",
        "五、相关品种联动分析",
        "六、后市展望与策略建议",
        "七、风险提示"
    ])
    
    # 核心观点
    add_content_slide(prs, "一、核心观点", [
        "玉米主力合约（C0）近期维持震荡上行格局，重心稳步上移",
        "自2月初2265元/吨低点反弹至当前2381元/吨，累计涨幅约5.1%",
        "技术面上方面临2400-2450元/吨压力区，下方支撑2350元/吨",
        "操作建议：2350-2400元/吨区间逢低做多，目标2450-2500元/吨",
        "止损位：2320元/吨（跌破MA20）"
    ])
    
    # 关键数据表格
    add_table_slide(prs, "关键数据速览", 
        ['指标', '数值', '说明'],
        [
            ['最新收盘价', '2381元/吨', '主力合约C0'],
            ['60日最高', '2443元/吨', '2026年3月9日'],
            ['60日最低', '2183元/吨', '前期支撑'],
            ['最新持仓', '138.1万手', '较前期高点回落'],
            ['月涨幅', '5.03%', '震荡上行'],
        ]
    )
    
    # 价格走势图
    add_image_slide(prs, "二、行情回顾：价格走势", 
                   f"{image_dir}/chart1_price.png",
                   "玉米期货主力合约60日价格走势（含MA5/MA10/MA20）")
    
    # 持仓量变化图
    add_image_slide(prs, "二、行情回顾：量价分析", 
                   f"{image_dir}/chart2_volume.png",
                   "持仓量与成交量变化趋势")
    
    # 基本面分析
    add_two_column_slide(prs, "三、基本面分析",
        "看多因素",
        ["南美天气风险：巴西二季玉米关键期", "国内政策托底：收储政策持续", "需求边际改善：养殖利润修复", "渠道库存偏低：补库需求支撑"],
        "看空因素",
        ["新作面积增加预期", "南美新季玉米上市", "全球经济不确定性", "技术面前期高点压力"]
    )
    
    # 技术面分析
    add_table_slide(prs, "四、技术面分析：关键价位", 
        ['位置', '价格区间', '技术意义'],
        [
            ['压力位1', '2400-2410元/吨', '整数关口压力'],
            ['压力位2', '2443元/吨', '前期高点（3月9日）'],
            ['支撑位1', '2350-2360元/吨', 'MA10附近支撑'],
            ['支撑位2', '2320元/吨', 'MA20附近强支撑'],
        ]
    )
    
    # 相关品种联动
    add_image_slide(prs, "五、相关品种联动分析", 
                   f"{image_dir}/chart3_correlation.png",
                   "玉米/豆粕/淀粉/生猪价格走势对比（归一化）")
    
    # 策略建议
    add_content_slide(prs, "六、后市展望与策略建议", [
        "方向判断：震荡偏多，逢低试多",
        "入场区间：2350-2400元/吨",
        "目标价位：2450-2500元/吨",
        "止损价位：2320元/吨（跌破MA20）",
        "仓位建议：轻仓试多，突破2443后加仓",
        "持有周期：1-2个月"
    ])
    
    # 风险提示
    add_content_slide(prs, "七、风险提示", [
        "天气风险：南美天气变化可能影响全球玉米供应预期",
        "政策风险：收储政策力度变化可能影响市场情绪",
        "宏观风险：全球经济形势变化可能影响大宗商品整体走势",
        "资金风险：持仓量快速变化可能导致价格波动加剧"
    ])
    
    # 封底
    add_footer_slide(prs)
    
    # 保存
    output_path = '/root/.openclaw/workspace/玉米期货投研报告_方正中期_20260311.pptx'
    prs.save(output_path)
    print(f"✅ PPT生成完成！")
    print(f"📁 文件路径: {output_path}")

if __name__ == '__main__':
    main()
