#!/usr/bin/env python3
"""根据模板 + 数据 JSON 配置文件 → 生成 PPT

用法: python generate_ppt.py <template.pptx> <config.json> <output.pptx>

config.json 格式:
{
  "text_data": { "标题": "xxx", "日期": "2024-12-05" },
  "chart_configs": {
    "图表名": {
      "csv_path": "data.csv",
      "categories_col": "日期",
      "series_config": [
        {"key": "列名", "name": "显示名", "type": "bar", "axis": "primary"},
        {"key": "列名2", "name": "显示名2", "type": "line", "axis": "secondary"}
      ],
      "style": {
        "color_scheme": "aim00",
        "line_width_pt": 2.0,
        "marker_style": "none"
      },
      "layout": {
        "title": "图表标题",
        "legend": {"position": "top", "font_size_pt": 9, "font_name": "黑体"},
        "value_axis": {"number_format": "0%", "font_size_pt": 9},
        "secondary_value_axis": {"number_format": "#,##0", "font_size_pt": 9},
        "date_axis": {"number_format": "yyyy/mm", "base_unit": "days"}
      }
    }
  }
}
"""

import sys
import json
import argparse
from pathlib import Path

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

import pandas as pd
from pptx.enum.chart import XL_LEGEND_POSITION

from ppt_station.template.replacer import TemplateReplacer
from ppt_station.chart_builder.styles import StyleConfig
from ppt_station.chart_builder.layout import ChartLayoutConfig, LegendConfig, ValueAxisConfig
from ppt_station.chart_builder.date_axis import DateAxisConfig


LEGEND_POSITION_MAP = {
    "top": XL_LEGEND_POSITION.TOP,
    "bottom": XL_LEGEND_POSITION.BOTTOM,
    "left": XL_LEGEND_POSITION.LEFT,
    "right": XL_LEGEND_POSITION.RIGHT,
    "corner": XL_LEGEND_POSITION.CORNER,
}


def build_chart_config(chart_name: str, chart_def: dict, config_dir: Path) -> dict:
    """从 JSON 配置构建图表配置字典（供 TemplateReplacer 使用）"""

    # 加载 CSV 数据
    csv_path = config_dir / chart_def["csv_path"]
    if not csv_path.exists():
        print(f"  错误: CSV 文件不存在: {csv_path}", file=sys.stderr)
        sys.exit(1)

    df = pd.read_csv(str(csv_path))

    # 转换日期列
    categories_col = chart_def["categories_col"]
    if categories_col in df.columns:
        try:
            df[categories_col] = pd.to_datetime(df[categories_col])
        except Exception:
            pass  # 非日期列保持原样

    series_config = chart_def["series_config"]

    # 构建样式配置
    style_def = chart_def.get("style", {})
    style_config = StyleConfig(
        color_scheme=style_def.get("color_scheme", "aim00"),
        line_width_pt=style_def.get("line_width_pt", 2.0),
        marker_style=style_def.get("marker_style", "none"),
    )

    # 构建布局配置
    layout_def = chart_def.get("layout", {})

    legend_def = layout_def.get("legend", {})
    legend_pos = LEGEND_POSITION_MAP.get(legend_def.get("position", "top"), XL_LEGEND_POSITION.TOP)
    legend_config = LegendConfig(
        position=legend_pos,
        font_size_pt=legend_def.get("font_size_pt", 9),
        font_name=legend_def.get("font_name", "黑体"),
    )

    va_def = layout_def.get("value_axis", {})
    value_axis_config = ValueAxisConfig(
        number_format=va_def.get("number_format", "0%"),
        font_size_pt=va_def.get("font_size_pt", 9),
        font_name=va_def.get("font_name", "黑体"),
        has_major_gridlines=va_def.get("has_major_gridlines", False),
    )

    sva_def = layout_def.get("secondary_value_axis", {})
    secondary_value_axis_config = ValueAxisConfig(
        number_format=sva_def.get("number_format", "#,##0"),
        font_size_pt=sva_def.get("font_size_pt", 9),
        font_name=sva_def.get("font_name", "黑体"),
        has_major_gridlines=sva_def.get("has_major_gridlines", False),
    )

    layout_config = ChartLayoutConfig(
        title=layout_def.get("title", ""),
        legend_config=legend_config,
        value_axis_config=value_axis_config,
        secondary_value_axis_config=secondary_value_axis_config,
    )

    # 日期轴配置
    da_def = layout_def.get("date_axis", {})
    if da_def:
        label_interval = da_def.get("major_unit", len(df) // 7)
        date_axis_config = DateAxisConfig(
            base_unit=da_def.get("base_unit", "days"),
            major_unit=label_interval,
            number_format=da_def.get("number_format", "yyyy/mm"),
        )
        layout_config.date_axis_config = date_axis_config

    return {
        "df": df,
        "categories_col": categories_col,
        "series_config": series_config,
        "style_config": style_config,
        "layout_config": layout_config,
    }


def main():
    parser = argparse.ArgumentParser(description="模板替换生成 PPT")
    parser.add_argument("template", help="模板 .pptx 文件路径")
    parser.add_argument("config", help="配置 .json 文件路径")
    parser.add_argument("output", help="输出 .pptx 文件路径")
    args = parser.parse_args()

    template_path = Path(args.template)
    config_path = Path(args.config)
    output_path = Path(args.output)

    if not template_path.exists():
        print(f"错误: 模板文件不存在: {template_path}", file=sys.stderr)
        sys.exit(1)
    if not config_path.exists():
        print(f"错误: 配置文件不存在: {config_path}", file=sys.stderr)
        sys.exit(1)

    with open(config_path, "r", encoding="utf-8") as f:
        config = json.load(f)

    config_dir = config_path.parent

    # 重定向 print 到 stderr
    old_stdout = sys.stdout
    sys.stdout = sys.stderr

    # 构建图表配置
    chart_configs = {}
    for chart_name, chart_def in config.get("chart_configs", {}).items():
        print(f"构建图表配置: {chart_name}")
        chart_configs[chart_name] = build_chart_config(chart_name, chart_def, config_dir)

    # 执行替换
    text_data = config.get("text_data", {})
    replacer = TemplateReplacer(template_path)
    replacer.replace(data=text_data, chart_configs=chart_configs)

    output_path.parent.mkdir(parents=True, exist_ok=True)
    replacer.save(output_path)

    sys.stdout = old_stdout
    print(json.dumps({"status": "ok", "output": str(output_path)}))


if __name__ == "__main__":
    main()
