"""商品 AI 补全核心：无 HTTP 壳，供批量 Celery 任务与前端调用。"""
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.models.tenant_settings import TenantSettings
from app.core.ai_utils import call_ai, resolve_ai_extra

# AI 只允许补这些「文案类」空字段；价格/SKU/库存/分类 ID 一律不由 AI 猜
ENRICHABLE = (
    "description", "ai_description", "meta_title", "meta_description", "seo_keywords",
    "name_en", "description_en", "ai_description_en", "meta_title_en",
    "meta_description_en", "seo_keywords_en",
)


def missing_fields(row: dict) -> list[str]:
    """返回 row 中为空、且属于 AI 可补集合的字段名。缺失的键视为空。"""
    return [f for f in ENRICHABLE if not str(row.get(f) or "").strip()]


def _build_assist_prompt(row: dict, search_context: str, store_context: str, lang: str) -> str:
    """迁移自 ai_product.py 的 product_assist 提示词模板（纯字符串构建，无 HTTP 依赖）。"""
    name = row.get("name") or ""
    keywords = row.get("keywords") or ""
    category = row.get("category") or ""
    lang_hint = "用中文回复" if lang == "zh" else "Reply in English"
    return f"""你是资深电商运营专家，精通商品文案撰写、SEO 优化和客服知识库建设。
请仔细阅读以下商品信息和搜索参考资料，为该商品生成完整、专业、详细的电商文案。

⚠️ 核心原则：只写搜索资料中能确认的事实，不要编造任何具体数据。
对于无法确认的信息（如成分表、保质期、热量、产地等），不要猜测，直接写"详情请咨询在线客服"。
宁可少写也不要写错，错误信息会损害店铺信誉。

═══ 商品信息 ═══
名称：{name}
关键词：{keywords or "无"}
分类：{category or "未指定"}

═══ 本店铺数据（用于保持风格一致） ═══
{store_context}

═══ 网络搜索参考资料（请充分利用这些真实信息） ═══
{search_context}

═══ 输出要求 ═══
请严格只返回以下 JSON（不要任何额外文字、解释或 markdown）：
{{
  "description": "400-600字详细商品描述。要求：①开头一句话概括商品核心卖点；②分段介绍产品特色（如原料/工艺/口感/功效/设计亮点等，只写搜索资料中能确认的信息）；③使用场景和适用人群（如送礼、自用、聚会、日常等）；④品质保障或品牌背景（如有搜索到的信息）。用自然流畅的语言，避免堆砌关键词，适合直接作为商品详情页展示。对于无法确认的具体参数不要编造。",
  "meta_title": "SEO标题，50字以内。格式建议：品牌名+商品名+核心卖点+规格。",
  "meta_description": "SEO摘要，120-160字。用一段完整的话概括商品最大亮点、适用场景和购买理由，吸引用户从搜索结果中点击进来。",
  "tags": ["标签1", "标签2", "标签3", "标签4", "标签5", "标签6", "标签7", "标签8"],
  "ai_description": "供AI客服读取和搜索的知识库文本（不在前台展示），要求200-350字，格式如下：\\n第一行：8~15个搜索关键词和同义词（空格分隔），覆盖商品名、品牌名、品类名、口语化叫法、英文名等，越全面用户问询时命中率越高。\\n第二行起分要点详写：\\n· 商品基本信息（规格/容量等，只写搜索资料中明确提到的数据）\\n· 口感/外观/使用体验描述\\n· 适用场景（办公、运动、聚餐、送礼等）\\n· 与同类商品的差异和优势\\n· 常见客户问题预判及回答要点（对于无法确认的具体数据如保质期、成分、热量等，统一回答"详情请咨询在线客服"，不要编造数字）\\n· 搭配推荐或购买建议",
  "name_en": "商品名称的地道英文（符合英文电商命名习惯，非逐字直译）",
  "description_en": "上面 description 的英文版（意译，地道流畅）",
  "meta_title_en": "上面 meta_title 的英文版",
  "meta_description_en": "上面 meta_description 的英文版",
  "ai_description_en": "上面 ai_description 的英文版",
  "tags_en": ["english tag1", "english tag2", "..."]
}}

{lang_hint}。以上 _en / tags_en 字段始终用英文填写，作为对应中文字段的翻译。只返回 JSON。"""


async def enrich_one_pure(row: dict, extra: dict, search_context: str, store_context: str, lang: str = "zh") -> dict:
    """单行商品文案补全：只填空的可补字段，已有值一律保留。无 HTTP 依赖，供批量任务复用。"""
    missing = missing_fields(row)
    if not missing:
        return dict(row)

    from app.api.routers.admin.ai_product import _parse_ai_json

    prompt = _build_assist_prompt(row, search_context, store_context, lang)
    raw = await call_ai(prompt, extra, timeout=300, max_tokens=4096)
    data = _parse_ai_json(raw, row.get("name", ""), row.get("category", ""))

    out = dict(row)
    for f in missing:
        if f == "seo_keywords":
            continue  # 下面单独用 tags 处理
        val = data.get(f)
        if val:
            out[f] = val

    if "seo_keywords" in missing and not str(out.get("seo_keywords") or "").strip():
        tags = data.get("tags") or []
        if tags:
            out["seo_keywords"] = " ".join(tags)

    # 翻译：既然已经调了 AI，顺带把空的英文字段一起填（方案b：一次调用出中英）
    for f in ("name_en", "description_en", "ai_description_en", "meta_title_en", "meta_description_en"):
        if not str(out.get(f) or "").strip() and data.get(f):
            out[f] = data[f]
    if not str(out.get("seo_keywords_en") or "").strip():
        tags_en = data.get("tags_en") or []
        if tags_en:
            out["seo_keywords_en"] = " ".join(tags_en)

    return out


async def get_ai_extra(db: AsyncSession, tenant_id: int) -> dict:
    """读取租户 AI 配置并按优先级解析；未启用则抛 HTTPException。合并三处重复样板。"""
    from fastapi import HTTPException
    s = (await db.execute(
        select(TenantSettings).where(TenantSettings.tenant_id == tenant_id)
    )).scalar_one_or_none()
    extra = (s.extra or {}) if s else {}
    if not extra.get("ai_enabled"):
        raise HTTPException(status_code=400, detail="AI 功能未启用，请先在系统设置 → AI 配置中开启")
    return await resolve_ai_extra(db, tenant_id, extra)
