"""
_scoring_dims.py — 五维打分逻辑（单一职责：计算层）
词表常量 + 每维打分函数，由 text_scoring.score_copy 调用
"""
from __future__ import annotations
import re
from typing import Any

from .constants import SCORE_WEIGHTS, BANNED_WORDS_DEFAULT, BANNED_VISUAL_WORDS, INTERNAL_COPY_HINTS

_EMOTION_WORDS = ["谁懂", "绝了", "姐妹", "宝子", "挖到", "救星", "离不开",
                  "闭眼入", "冲", "不踩雷", "后悔没早买"]
_SCENE_WORDS   = ["通勤", "上班", "办公室", "工位", "宿舍", "出门", "旅行",
                  "居家", "运动", "带娃", "约会", "熬夜", "换季", "饭后",
                  "早餐", "下午", "加班", "外食", "日常", "早八", "学生党", "新手", "宝妈"]
_CATEGORY_WORDS: dict[str, list[str]] = {
    "美妆护肤":  ["肤", "妆", "质地", "服帖", "清透", "水润", "自然", "上脸", "底妆"],
    "个护护理":  ["手", "护理", "干", "黏", "吸收", "滋润", "粗糙", "倒刺", "随身", "质地"],
    "食品饮品":  ["口感", "入口", "味道", "冲泡", "杯", "工位", "囤", "不腻", "清爽"],
    "营养健康":  ["成分", "日常", "坚持", "习惯", "补给", "安心", "配方"],
    "家居生活":  ["收纳", "省事", "清洁", "桌面", "厨房", "租房", "细节", "高频"],
    "服饰穿搭":  ["上身", "版型", "面料", "通勤", "显瘦", "搭配", "质感"],
    "通用好物":  ["实用", "场景", "细节", "省事", "日常", "高频"],
}


def _has_any(text: str, words: list[str]) -> bool:
    return any(w.lower() in text.lower() for w in words)


def _cat_words(category: str) -> list[str]:
    return _CATEGORY_WORDS.get(category, _CATEGORY_WORDS["通用好物"])


def score_title(title: str, cat_words: list[str], w: dict) -> dict:
    ts = 0
    if 6 <= len(title) <= 34: ts += 8
    if re.search(r"[0-9一二三四五六七八九十几]|最近|这支|这个|每天|早八|学生党|新手|宝妈|懒人|伪素颜", title): ts += 5
    if _has_any(title, _SCENE_WORDS): ts += 6
    if _has_any(title, cat_words):   ts += 5
    if re.search(r"[！!?？]|救星|不踩雷|闭眼入|会回购|被问|惊喜|加分|常备|省心|实用|别乱选|放心|有气色", title): ts += 6
    if re.search(r"救星|绝了|挖到|偷偷|被问|离不开|后悔|拿捏|香|包里|回购|常备|工位|换季", title): ts += 4
    ts = min(ts, w["title"])
    return {"item": "标题吸引力", "score": ts, "max": w["title"],
            "note": "标题有明确人群/场景钩子" if ts >= 18 else "建议补充人群、场景或强钩子"}


def score_emotion(full: str, w: dict) -> dict:
    es = 0
    if _has_any(full, _EMOTION_WORDS): es += 10
    if _has_any(full, _SCENE_WORDS):   es += 8
    if re.search(r"不假白|不卡|不搓泥|没底气|纠结|救|不黏|不腻|踩雷|麻烦|翻车", full): es += 7
    if re.search(r"姐妹|宝子|室友|同事|我自己|实测|亲测|上脸|出门|工位|宿舍|家里", full): es += 5
    if re.search(r"[✅✨🌿💧📦🔍🧡🪞🧴🍃🥹😭👍]", full): es += 3
    es = min(es, w["emotion"])
    return {"item": "情绪共鸣", "score": es, "max": w["emotion"],
            "note": "口语感和痛点表达较充分" if es >= 18 else "建议增加真实痛点和口语化表达"}


def score_selling(copy: dict, full: str, selling_points: list, w: dict) -> dict:
    bs = 0
    matched = [pt for pt in selling_points if any(kw in full for kw in str(pt).split()[:3])]
    if len(matched) >= 1: bs += 7
    if len(matched) >= 2: bs += 4
    if re.search(r"方便|自然|清爽|质地|口感|成分|实测|亲测|场景|随身|省事|高频|性价比|好用|适合|推荐", full): bs += 8
    if copy.get("buyingPoint") or re.search(r"分钟|出门|通勤|办公室|宿舍|居家|换季|工位|旅行", full): bs += 9
    if copy.get("coverTitle") or copy.get("imageBrief"): bs += 4
    bs = min(bs, w["selling"])
    return {"item": "买点表达", "score": bs, "max": w["selling"],
            "note": "卖点已转成用户可感知买点" if bs >= 18 else "建议把功能卖点翻译成使用场景和结果"}


def score_keyword(copy: dict, tags: str, keywords: list, w: dict) -> dict:
    ks = 0
    matched = [k for k in keywords if str(k).replace("#", "") in tags + str(copy.get("content",""))]
    if len(matched) >= 1: ks += 6
    if len(matched) >= 2: ks += 5
    if len(copy.get("tags", [])) >= 3: ks += 5
    if "#" in tags: ks += 4
    if len(copy.get("tags", [])) >= 5: ks += 4
    ks = min(ks, w["keyword"])
    note = f"覆盖：{'、'.join(matched)}" if matched else "建议补充品类词和长尾词"
    return {"item": "关键词覆盖", "score": ks, "max": w["keyword"], "note": note}


def score_compliance(full: str, bwords: list[str], w: dict) -> tuple[dict, list[str]]:
    found_banned = [bw for bw in bwords if bw.lower() in full.lower()]
    found_hints  = [hw for hw in INTERNAL_COPY_HINTS if hw in full]
    cs = 0 if (found_banned or found_hints) else w["compliance"]
    note = (f"含禁用词：{'、'.join(found_banned)}" if found_banned
            else (f"正文混入内部提示：{'、'.join(found_hints)}" if found_hints else "未发现禁用词"))
    return {"item": "合规性", "score": cs, "max": w["compliance"], "note": note}, found_banned + found_hints
