"""重新对 vehicle_hotspots 做协议评分：加入"必须有具体车型"规则
检测方式：model字段不为空 OR 标题包含车型关键词模式
"""

import json, os, re, urllib.request
from datetime import datetime

DEEPSEEK_API_URL = 'https://api.deepseek.com/v1/chat/completions'
BATCH_SIZE = 10

# 车型关键词模式（标题中检测具体车型名）
MODEL_PATTERNS = [
    r'[A-Z][0-9A-Za-z\s\-]+[0-9]',           # Model X, G9, C5 X, S07
    r'[0-9]+款',                                 # 2026款
    r'[A-Z][0-9]+\s*(?:EV|PHEV|HEV|SUV|MPV)', # 钛7 EV
    r'GT[0-9]',                                  # GT7
    r'L[0-9]*\b',                                # L05, L
    r'[A-Z]+[0-9]+\s*款',                       # C5 X款, ET5款
    r'[耀|腾|界|舟|风]+\d+',                    # G919
    r'^[^\s]+[0-9]',                             # 开头带数字款：长安猎手K50
]


def has_vehicle_model(item):
    """检测条目是否有具体车型"""
    # 直接检查 model 字段
    model = item.get('model', '') or ''
    if model.strip():
        return True
    
    # 从标题中检测车型模式
    title = item.get('title', '')
    patterns = [
        r'[A-Z][0-9]',             # C5, M8, E8, S07, G9, L05, ET5
        r'[A-Za-z]+\s*EV',         # 钛7 EV, 纯电EV
        r'[0-9]+款\s*[^\s]+',      # 2026款ET5
        r'猎手K[0-9]+',            # K50
        r'钛7|泰山X8|豪越L|星途ES|凡尔赛C5|星光L|悦意08|欧拉7',
        r'蒙迪欧运动版|悍野版|冠军纪念版',
        r'新版本上市',
    ]
    for p in patterns:
        if re.search(p, title):
            return True
    return False


KEYWORD_MAP = {
    '新车': ['上市', '发布', '预售', '亮相', '首发', '开启预售', '新车'],
    '电动化': ['电动', '纯电', 'EV', '续航', '充电', '新能源', '纯电动'],
    '混动': ['混动', 'PHEV', '增程', '轻混', '混动版', '插混'],
    '智能化': ['智能', '智驾', '自动驾驶', '座舱', '激光雷达', '乾崑', '天枢'],
    '价格/权益': ['售价', '万元', '万起', '补贴', '优惠', '限时', '福利', '降价', '置换', '金融', '低至'],
    '用户运营': ['用户', '私域', '社群', '会员', '粉丝', '圈层', '忠诚', '车主', '社区', '互动', '打卡'],
    '本土化': ['本土化', '本土', '中国风', '国潮', '传统', '文化', '非遗', '国货', '中国'],
    '线下体验': ['体验', '场景', '快闪', '线下', '门店', '沉浸', '试驾', '到店', '工厂', '探访'],
    'AI/数字化': ['AI', '人工智能', '数字化', '数据', '算力', '算法', '大模型', '智能系统', '芯片', '半导体'],
    '内容营销': ['短剧', '内容', '短视频', '直播', '共创', 'UGC', '短片', '视频', '广告', '种草'],
    '体育营销': ['世界杯', '奥运', '体育', '赛事', '运动员', '欧冠', '决赛', '球迷', '观赛', '比赛', '球场'],
}
WEIGHTS = {
    '新车': 0.99, '电动化': 0.74, '混动': 0.38, '智能化': 0.55,
    '价格/权益': 0.65, '用户运营': 0.71, '本土化': 0.59,
    '线下体验': 0.44, 'AI/数字化': 0.28, '内容营销': 0.15,
    '体育营销': 0.0,  # 车型板块不直接用体育营销权重，但需要检测
}
TOTAL_W = sum(WEIGHTS.values())


def get_deepseek_key():
    cfg_path = '/root/.openclaw/openclaw.json'
    try:
        with open(cfg_path) as f:
            cfg = json.load(f)
        return cfg['models']['providers']['deepseek']['apiKey']
    except:
        return None


def stage1_score(item):
    """Stage 1: 关键词加权 + 必须有具体车型"""
    text = item.get('title', '') + ' ' + item.get('summary', '')
    text_lower = text.lower()
    
    # 必须有具体车型，否则降分
    if not has_vehicle_model(item):
        # 车型相关行业分析给15分基础，纯无关给0
        has_auto_keywords = any(kw in text_lower for kw in ['汽车', '车市', '车展', '销量', '新能源', '降价'])
        return 15 if has_auto_keywords else 0, []
    
    hit_weight = 0.0
    hit_dims = []
    for dim, keywords in KEYWORD_MAP.items():
        w = WEIGHTS.get(dim, 0)
        if w == 0:
            continue
        for kw in keywords:
            if kw.lower() in text_lower:
                hit_weight += w
                hit_dims.append(dim)
                break
    
    raw = (hit_weight / TOTAL_W) * 100
    bonus = min(len(hit_dims) * 5, 20)
    score = min(100, raw + bonus)
    
    # 世界杯加成
    now = datetime.now()
    if (now.month == 6 and now.day >= 12) or (now.month == 7 and now.day <= 20):
        if any(kw in text_lower for kw in ['世界杯', '赛事', '观赛', '球迷', '足球', '世界杯赞助']):
            score = min(100, score * 1.4)
    
    return score, hit_dims


PROTOCOL_PROMPT = """你是现代汽车营销情报分析师。请严格按以下规则对{count}条车型热点进行评分。

## 核心规则
1. 必须是具体车型相关的消息（上市/预售/降价/技术突破等）
2. 排除：纯行业分析、无具体车型的综述、与汽车无关的内容

## 评分映射
- ≥ 65: strong_select
- 45-64: select
- 25-44: backup
- < 25: reject

## 标签体系
event_type: 竞品上市 | 竞品预售 | 竞品降价 | 技术合作 | 世界杯体育营销 | 品牌营销案例 | 其他
industry_tags: 油车 | 轻混 | PHEV | 纯电 | SUV | MPV | 智能驾驶 | 价格
business_tags: 竞品拦截 | 提高销售转化 | 提高品牌影响 | 提升用户信任 | 促进试驾 | 促进到店 | 强化低用车成本心智

## 输出格式（严格JSON数组）
[
  {{
    "idx": 1,
    "selection_suggestion": "strong_select",
    "selection_reason": "15字内理由",
    "marketing_opportunity": "20字内启示",
    "scores": {{
      "hyundai_relevance_score": 0-100,
      "conversion_value_score": 0-100,
      "marketing_actionability_score": 0-100,
      "brand_influence_score": 0-100,
      "customer_loyalty_score": 0-100,
      "competitor_threat_score": 0-100,
      "overall_tag_value_score": 0-100
    }},
    "event_type": "",
    "industry_tags": [],
    "business_tags": [],
    "risk_tags": ["无明显风险"]
  }},
  ...
]

待评数据：
{items_text}"""


def call_deepseek(items):
    key = get_deepseek_key()
    if not key:
        return None
    lines = []
    for i, it in enumerate(items, 1):
        lines.append("[%d] 标题：%s" % (i, it.get('title', '')))
        lines.append("    摘要：%s" % it.get('summary', ''))
    items_text = "\n".join(lines)
    
    prompt = PROTOCOL_PROMPT.format(count=len(items), items_text=items_text)
    
    payload = json.dumps({
        "model": "deepseek-chat",
        "messages": [{"role": "user", "content": prompt}],
        "temperature": 0.3,
        "max_tokens": 4000
    }).encode()
    
    req = urllib.request.Request(
        DEEPSEEK_API_URL, data=payload,
        headers={
            'Authorization': 'Bearer ' + key,
            'Content-Type': 'application/json'
        }
    )
    try:
        resp = urllib.request.urlopen(req, timeout=90)
        result = json.loads(resp.read().decode('utf-8'))
        reply = result['choices'][0]['message']['content'].strip()
        json_start = reply.find('[')
        json_end = reply.rfind(']') + 1
        if json_start >= 0 and json_end > json_start:
            return json.loads(reply[json_start:json_end])
        print("  ⚠️ 解析失败: %s" % reply[:150])
        return None
    except Exception as e:
        print("  ❌ DeepSeek失败: %s" % e)
        return None


def main():
    path = '/data/news/json/origin_data/0615data.json'
    with open(path, 'r', encoding='utf-8') as f:
        data = json.load(f)
    
    for section in data:
        if section.get('name') != 'vehicle_hotspots':
            continue
        
        items = section.get('list', [])
        total = len(items)
        print("车型热点共 %d 条" % total)
        
        # Stage 1: 关键词+车型检测
        print("\n▶ Stage 1 关键词评分（含具体车型检测）...")
        scored = []
        for it in items:
            s1, dims = stage1_score(it)
            has_model = has_vehicle_model(it)
            scored.append((s1, has_model, it))
        
        # 排序：有车型的排前面，再按分数
        scored.sort(key=lambda x: (x[1], x[0]), reverse=True)
        
        # 取前15条（必须有车型）
        top15 = [x for x in scored if x[1]][:15]
        rest = [x for x in scored if x not in top15]
        
        print("  有具体车型的条目: %d 条" % sum(1 for _, h, _ in scored if h))
        print("  前15名分数范围: %.0f-%.0f" % (top15[-1][0], top15[0][0]))
        print("  其余 %d 条直接设为 reject" % (total - len(top15)))
        
        # 未进入前15的全部reject
        in_top15 = {id(it): True for _, _, it in top15}
        for it in items:
            if id(it) not in in_top15:
                it['yesorno'] = ''
                # 清理协议字段
                for f in ['protocol_scores', 'selection_suggestion', 'selection_reason', 'marketing_opportunity']:
                    it.pop(f, None)
        
        # Stage 2: DeepSeek对前15条评分
        print("\n▶ Stage 2 DeepSeek协议评分（15条）...")
        top_items = [it for _, _, it in top15]
        for i, it in enumerate(top_items, 1):
            print("  [%d] %s" % (i, it.get('title','')[:50]))
        
        results = []
        for start in range(0, 15, BATCH_SIZE):
            batch = top_items[start:start+BATCH_SIZE]
            batch_num = start // BATCH_SIZE + 1
            print("  批次 %d/2（%d条）..." % (batch_num, len(batch)))
            r = call_deepseek(batch)
            if r and len(r) == len(batch):
                results.extend(r)
                print("  ✅ 返回成功")
            else:
                for _ in batch:
                    results.append(None)
        
        # 写回
        updates = {'yes': 0, 'backup': 0, 'empty': 0}
        for idx, it in enumerate(top_items):
            r = results[idx] if idx < len(results) else None
            if r and isinstance(r, dict):
                scores = r.get('scores', {})
                overall = scores.get('overall_tag_value_score', 50)
                # 必须有车型才给yes
                if overall >= 45 and has_vehicle_model(it):
                    it['yesorno'] = 'yes'
                    updates['yes'] += 1
                elif overall >= 25:
                    it['yesorno'] = 'backup'
                    updates['backup'] += 1
                else:
                    it['yesorno'] = ''
                    updates['empty'] += 1
                
                it['protocol_scores'] = scores
                it['selection_suggestion'] = r.get('selection_suggestion', '')
                it['selection_reason'] = r.get('selection_reason', '')
                it['marketing_opportunity'] = r.get('marketing_opportunity', '')
                it['event_type'] = r.get('event_type', '')
                it['business_tags'] = r.get('business_tags', [])
                it['risk_tags'] = r.get('risk_tags', [])
            else:
                # fallback: 没返回结果的保持原有评分
                pass
        
        print("\n▶ 最终分布:")
        for k, v in updates.items():
            print("  %s: %d条" % (k, v))
        break
    
    with open(path, 'w', encoding='utf-8') as f:
        json.dump(data, f, ensure_ascii=False, indent=2)
    print("\n✅ 已更新 %s" % path)


if __name__ == '__main__':
    main()
