"""
违禁词三级处理（扒 copy.js sanitizePlanningText 扩展为三级）
🟢 auto_fix  = 自动改写（replacement 字段给出替换词）
🟡 soft_warn = 软提示（返回建议词，不阻塞）
🔴 hard_block= 硬拦截（直接返回 None，拦住发布）

词库来自数据库 banned_words 表（level + replacement 字段），
DB 未配时用本模块内置默认词库作冷启动。
"""
from __future__ import annotations
import re
from dataclasses import dataclass, field
from typing import Literal

BannedLevel = Literal["auto_fix", "soft_warn", "hard_block"]


@dataclass
class BannedWordEntry:
    word: str
    level: BannedLevel
    replacement: str | None = None  # auto_fix 时提供替换词


# ── 默认词库（北哥回填解读与落点 §4.3，数据库未配时使用）─
DEFAULT_BANNED_WORDS: list[BannedWordEntry] = [
    # 功效违禁（auto_fix：改写成合规表达，对应北哥"提亮肤色感/改善暗沉观感"）
    BannedWordEntry("美白", "auto_fix", "提亮肤色感"),
    BannedWordEntry("祛斑", "auto_fix", "改善暗沉观感"),
    # 功效违禁（hard_block：无法合规改写，直接拦截）
    BannedWordEntry("速效", "hard_block"),
    BannedWordEntry("医用", "hard_block"),
    BannedWordEntry("药妆", "hard_block"),
    BannedWordEntry("强效焕白", "hard_block"),
    # 保证性词（soft_warn）
    BannedWordEntry("绝对", "soft_warn"),
    BannedWordEntry("第一名", "soft_warn"),
    BannedWordEntry("再也不", "soft_warn"),
    # 夸张词（soft_warn）
    BannedWordEntry("杀疯了", "soft_warn"),
    BannedWordEntry("秒杀", "soft_warn"),
    BannedWordEntry("震撼", "soft_warn"),
    # AI 味词（auto_fix，置换为口语表达；同时在 _NEGATIVE_WORDS prompt负向约束里已禁止AI写进正文）
    BannedWordEntry("神器", "auto_fix", "好用的"),
    BannedWordEntry("福音", "auto_fix", "适合的"),
    BannedWordEntry("救急单品", "auto_fix", "随手备用的"),
    BannedWordEntry("遮羞布", "auto_fix", "底妆感"),          # 北哥原文补录
    BannedWordEntry("不仅而且", "auto_fix", "，另外"),
    BannedWordEntry("焕发", "auto_fix", "呈现"),
    BannedWordEntry("守护", "auto_fix", ""),
    BannedWordEntry("尽享", "auto_fix", "使用"),
    BannedWordEntry("日常维稳", "auto_fix", "日常保养"),
    BannedWordEntry("精简底妆", "auto_fix", "轻便底妆"),
    # 视觉违禁（hard_block，文案含这些词不许过）
    BannedWordEntry("前后对比", "hard_block"),
    BannedWordEntry("使用前后", "hard_block"),
    BannedWordEntry("变白", "auto_fix", "自然光泽感"),
    BannedWordEntry("瑕疵消失", "auto_fix", "妆感更服帖"),
]


@dataclass
class CheckResult:
    text: str                        # 原文（soft_warn/hard_block 场景下保持原文）
    fixed_text: str | None           # auto_fix 后的文本；其他级别为 None
    status: Literal["pass", "auto_fixed", "soft_warn", "hard_block"]
    found: list[dict] = field(default_factory=list)
    # found 每项: {"word": str, "level": BannedLevel, "replacement": str|None}


def check_and_fix(
    text: str,
    entries: list[BannedWordEntry] | None = None,
) -> CheckResult:
    """
    对一段文本做三级违禁词扫描。
    entries：优先用 DB 词条，为 None 时用默认词库。
    """
    word_list = entries if entries is not None else DEFAULT_BANNED_WORDS
    found: list[dict] = []
    working = text

    # 先扫描所有命中
    for entry in word_list:
        if entry.word.lower() in working.lower():
            found.append({
                "word": entry.word,
                "level": entry.level,
                "replacement": entry.replacement,
            })

    if not found:
        return CheckResult(text=text, fixed_text=None, status="pass", found=[])

    # 有 hard_block → 直接拦截
    if any(f["level"] == "hard_block" for f in found):
        return CheckResult(text=text, fixed_text=None, status="hard_block", found=found)

    # 只有 soft_warn → 软提示，不改文字
    if any(f["level"] == "soft_warn" for f in found) and \
            all(f["level"] in ("soft_warn", "auto_fix") for f in found):
        # 仍执行 auto_fix 改写，但结果状态是 soft_warn（优先级高）
        for f in found:
            if f["level"] == "auto_fix" and f["replacement"] is not None:
                working = re.sub(re.escape(f["word"]), f["replacement"], working, flags=re.IGNORECASE)
        return CheckResult(text=text, fixed_text=working, status="soft_warn", found=found)

    # 只有 auto_fix → 自动改写，返回 fixed_text
    for f in found:
        if f["level"] == "auto_fix" and f["replacement"] is not None:
            working = re.sub(re.escape(f["word"]), f["replacement"], working, flags=re.IGNORECASE)
    return CheckResult(text=text, fixed_text=working, status="auto_fixed", found=found)


def build_entries_from_db(rows: list[dict]) -> list[BannedWordEntry]:
    """把 DB banned_words 行转成 BannedWordEntry 列表"""
    return [
        BannedWordEntry(
            word=r["word"],
            level=r["level"],
            replacement=r.get("replacement"),
        )
        for r in rows
        if r.get("word") and r.get("level") in ("auto_fix", "soft_warn", "hard_block")
    ]
