# -*- coding: utf-8 -*-
"""
pipeline.py：总入口 — 串起 数据校验 -> 渲染 -> (可选)样式迁移。

注意：本包不维护内置模板。调用方需要自己准备 .docx 模板文件，
并通过 template 参数传入路径。
"""
import os
import json

from .schema import validate, normalize
from .render_quote import render
from .style_transfer import transplant_style


def _load_data(data):
    """把 data 归一化为 dict：支持 dict 或 JSON 文件路径。"""
    if isinstance(data, str):
        if not os.path.isfile(data):
            raise FileNotFoundError(f"数据文件不存在: {data}")
        with open(data, "r", encoding="utf-8") as f:
            data = json.load(f)

    if not isinstance(data, dict):
        raise TypeError(f"data 必须是 dict 或 JSON 文件路径，实际类型: {type(data).__name__}")
    return data


def _load_meta_for_template(template_path):
    """如果模板同目录下存在 meta.json，则读取；否则返回空 dict。"""
    meta_file = os.path.join(os.path.dirname(template_path), "meta.json")
    if os.path.isfile(meta_file):
        with open(meta_file, "r", encoding="utf-8") as f:
            return json.load(f)
    return {}


def generate(data, template, out_path, style_ref=None):
    """生成报价文档。

    参数:
        data:      QuoteData dict（或 JSON 文件路径字符串）
        template:  模板 docx 文件路径
        out_path:  输出 docx 路径
        style_ref: 用户上传的样式参考 docx 路径（可选）

    返回:
        生成的 docx 绝对路径
    """
    data = _load_data(data)

    if not isinstance(template, str):
        raise TypeError(f"template 必须是文件路径字符串，实际类型: {type(template).__name__}")
    if not os.path.isfile(template):
        raise FileNotFoundError(f"模板文件不存在: {template}")
    template_path = os.path.abspath(template)

    # 归一化 + 校验
    data = normalize(data)
    errs = validate(data)
    if errs:
        raise ValueError("数据校验失败:\n" + "\n".join(errs))

    # 确保输出目录存在
    out_dir = os.path.dirname(os.path.abspath(out_path))
    if out_dir:
        os.makedirs(out_dir, exist_ok=True)

    # 渲染（优先读取同目录 meta.json 作为图片配置）
    meta = _load_meta_for_template(template_path)
    render(data, out_path, template_path, meta=meta)

    # 可选样式迁移
    if style_ref:
        if not os.path.isfile(style_ref):
            raise FileNotFoundError(f"样式参考文件不存在: {style_ref}")
        transplant_style(out_path, style_ref, out_path)

    return os.path.abspath(out_path)
