"""
app/services/ai_engine/benchmark_analyzer.py — 第2环 标杆8维分析引擎

复用 products.analyze_product_image 的 vision 范式，解耦成 service。
输入：爆款截图 bytes + 手填亮点；输出：8维配方 JSON（写入 benchmark_notes.features_json）。
key 链路遵基石B：plain_key 只活在调用方局部，本模块只收已构建的 clients。
"""
import json
import logging
import re

from app.services.ai_engine._benchmark_prompt import BENCHMARK_8DIM_PROMPT

logger = logging.getLogger(__name__)

# 8维字段顺序（与 prompt JSON key 一致；analyze_status 流转 done 时校验齐全）
DIM_KEYS = [
    "title_formula", "opening_hook", "content_structure", "selling_point_style",
    "emotion_tone", "target_audience", "topic_tags", "visual_rhythm",
]


def parse_benchmark_json(raw: str) -> dict:
    """从模型返回文本提取 JSON（容错 markdown ```json 包裹）。"""
    cleaned = re.sub(r"```json\s*", "", raw)
    cleaned = re.sub(r"```\s*", "", cleaned)
    m = re.search(r"\{[\s\S]*\}", cleaned)
    if not m:
        raise ValueError("标杆分析返回中未找到 JSON")
    return json.loads(m.group())


def fallback_benchmark(highlights: str | None = None) -> dict:
    """vision 失败兜底：保证 8 维不空手，标 source=fallback 供前端提示。"""
    note = highlights or "截图未体现"
    return {
        "title_formula": note, "opening_hook": note, "content_structure": note,
        "selling_point_style": note, "emotion_tone": note, "target_audience": note,
        "topic_tags": note, "visual_rhythm": note,
        "confidence": 0.4, "source": "fallback",
    }


async def analyze_benchmark(clients, screenshot: bytes | None, highlights: str | None) -> dict:
    """
    跑 8 维分析。截图走 vision；无截图但有手填亮点则把亮点拼进 prompt 兜底。
    返回结构化 8 维 dict（含 confidence/source）。失败不抛，返回 fallback。
    """
    prompt = BENCHMARK_8DIM_PROMPT
    if highlights:
        prompt = f"{prompt}\n\n运营补充的亮点描述（作为分析参考）：{highlights}"

    images = [screenshot] if screenshot else []
    try:
        if not images:
            # 无截图：纯文本兜底（gpt_vision_analyze 支持空图走文本）
            logger.info("analyze_benchmark: 无截图，走手填亮点文本分析")
        raw = await clients.gpt_vision_analyze(prompt, images)
        result = parse_benchmark_json(raw)
        result["source"] = "vision" if images else "text"
        return result
    except Exception as e:
        logger.warning("analyze_benchmark failed, fallback: %s", e)
        result = fallback_benchmark(highlights)
        result["warning"] = f"标杆分析失败，已兜底：{e}"
        return result
