"""平台规则引擎 - 各内容平台的规则和最佳实践"""

import re

PLATFORM_RULES: dict[str, dict] = {
    "wechat": {
        "name": "微信公众号",
        "icon": "wechat",
        "max_title_length": 22,
        "max_content_length": 20000,
        "min_content_length": 300,
        "supported_media": ["image", "video", "audio"],
        "max_images": 20,
        "best_publish_times": ["07:30-08:30", "11:30-12:30", "17:30-18:30", "20:30-22:00"],
        "best_publish_days": ["周二", "周四", "周六"],
        "format_features": {
            "supports_markdown": False,
            "supports_html": True,
            "max_heading_level": 3,
            "supports_code_block": True,
        },
        "rules": [
            "不得使用诱导分享/关注语句",
            "图片单张不超过10MB",
            "标题不含连续特殊符号（如!!!）",
            "正文不含外部链接（仅支持公众号链接和小程序）",
            "不得包含未经授权的商标/品牌名称",
        ],
        "seo_tips": [
            "首段包含核心关键词",
            "使用小标题分段（适配搜一搜）",
            "文末设置话题标签",
            "摘要控制在120字内",
        ],
    },
    "zhihu": {
        "name": "知乎",
        "icon": "zhihu",
        "max_title_length": 30,
        "max_content_length": 50000,
        "min_content_length": 500,
        "supported_media": ["image", "video"],
        "max_images": 50,
        "best_publish_times": ["09:00-10:00", "14:00-15:00", "20:00-22:00"],
        "best_publish_days": ["周一", "周三", "周五"],
        "format_features": {
            "supports_markdown": True,
            "supports_html": False,
            "max_heading_level": 4,
            "supports_code_block": True,
        },
        "rules": [
            "回答需针对问题本身",
            "不得过度营销或硬广",
            "引用需标注来源",
            "不得使用AI水文（内容需有信息增量）",
        ],
        "seo_tips": [
            "回答开头直接给出结论",
            "使用数据和案例支撑",
            "合理设置二级标题",
            "文末引导关注专栏",
        ],
    },
    "xiaohongshu": {
        "name": "小红书",
        "icon": "xiaohongshu",
        "max_title_length": 20,
        "max_content_length": 1000,
        "min_content_length": 100,
        "supported_media": ["image", "video"],
        "max_images": 18,
        "best_publish_times": ["07:00-09:00", "12:00-13:00", "18:00-20:00", "21:00-23:00"],
        "best_publish_days": ["周末", "周三"],
        "format_features": {
            "supports_markdown": False,
            "supports_html": False,
            "max_heading_level": 0,
            "supports_code_block": False,
            "supports_emoji": True,
        },
        "rules": [
            "首图质量决定点击率",
            "正文控制在300-800字",
            "话题标签3-8个",
            "不得出现其他平台引流信息",
            "图片不含水印",
        ],
        "seo_tips": [
            "标题含数字更吸引点击",
            "正文用短句+emoji分段",
            "话题标签放文末",
            "首句即核心观点",
        ],
    },
    "baijiahao": {
        "name": "百家号",
        "icon": "baidu",
        "max_title_length": 30,
        "max_content_length": 30000,
        "min_content_length": 800,
        "supported_media": ["image", "video"],
        "max_images": 30,
        "best_publish_times": ["08:00-09:00", "11:00-12:00", "17:00-18:00"],
        "best_publish_days": ["工作日"],
        "format_features": {
            "supports_markdown": False,
            "supports_html": True,
            "max_heading_level": 3,
            "supports_code_block": False,
        },
        "rules": [
            "原创内容优先推荐",
            "标题不含夸张/标题党词汇",
            "正文需含至少1张配图",
            "不得搬运/洗稿",
        ],
        "seo_tips": [
            "标题包含百度搜索热词",
            "文章结构化（H2小标题）",
            "适当添加内链",
            "发布后及时答复评论",
        ],
    },
    "douyin": {
        "name": "抖音",
        "icon": "douyin",
        "max_title_length": 55,
        "max_content_length": 5000,
        "min_content_length": 0,
        "supported_media": ["video", "image"],
        "max_images": 35,
        "best_publish_times": ["06:00-08:00", "12:00-13:00", "18:00-20:00", "22:00-23:00"],
        "best_publish_days": ["每天"],
        "format_features": {
            "supports_markdown": False,
            "supports_html": False,
            "max_heading_level": 0,
            "supports_code_block": False,
            "supports_emoji": True,
        },
        "rules": [
            "视频/图文需原创",
            "不得含其他平台水印",
            "话题标签2-5个",
            "文案简短有吸引力",
        ],
        "seo_tips": [
            "前3秒决定完播率",
            "标题含热点关键词",
            "评论区互动提升权重",
            "合适的话题+POI定位",
        ],
    },
    "toutiao": {
        "name": "今日头条",
        "icon": "toutiao",
        "max_title_length": 30,
        "max_content_length": 30000,
        "min_content_length": 500,
        "supported_media": ["image", "video"],
        "max_images": 30,
        "best_publish_times": ["07:00-08:00", "12:00-13:00", "18:00-19:00", "21:00-22:00"],
        "best_publish_days": ["每天"],
        "format_features": {
            "supports_markdown": False,
            "supports_html": True,
            "max_heading_level": 3,
            "supports_code_block": False,
        },
        "rules": [
            "标题不得标题党",
            "内容需有信息价值",
            "首发原创优先推荐",
            "配图清晰不模糊",
        ],
        "seo_tips": [
            "标题含核心关键词",
            "文章1500字以上推荐更高",
            "合理使用头条话题",
            "发布频率稳定提升权重",
        ],
    },
}


# 诱导分享/关注关键词
_INDUCING_PATTERNS = re.compile(
    r"(转发|分享|关注|点赞|收藏).{0,4}(领|获|得|拿|解锁|免费)",
    re.IGNORECASE,
)

# 连续特殊符号
_CONSECUTIVE_SYMBOLS = re.compile(r"[!！?？]{3,}")

# 外部链接（排除公众号和小程序链接）
_EXTERNAL_LINK = re.compile(
    r"https?://(?!mp\.weixin\.qq\.com|wx\.qq\.com|weixin://)[^\s<>)）]+",
    re.IGNORECASE,
)

# 标题党关键词
_CLICKBAIT_WORDS = {"震惊", "惊呆", "吓死", "笑死", "疯传", "刷屏", "出大事", "不敢相信"}

# 水印检测（简化：检测常见平台水印文本）
_WATERMARK_PATTERNS = re.compile(
    r"(抖音|快手|小红书|微博|B站|bilibili).*(水印|logo)",
    re.IGNORECASE,
)


class PlatformRuleEngine:
    """平台规则引擎"""

    def get_platforms(self) -> list[dict]:
        """获取所有支持平台列表"""
        return [
            {
                "id": key,
                "name": val["name"],
                "icon": val["icon"],
                "max_title_length": val["max_title_length"],
                "max_content_length": val["max_content_length"],
                "min_content_length": val["min_content_length"],
                "supported_media": val["supported_media"],
                "max_images": val["max_images"],
            }
            for key, val in PLATFORM_RULES.items()
        ]

    def get_platform_rules(self, platform: str) -> dict | None:
        """获取指定平台的完整规则"""
        return PLATFORM_RULES.get(platform)

    def validate_content(self, content: str, title: str, platform: str) -> dict:
        """
        校验内容是否符合平台规则

        返回: {
            "is_valid": bool,
            "score": int (0-100),
            "issues": [{"severity": "high|medium|low", "message": "..."}],
            "passed": ["规则1", "规则2"]
        }
        """
        rules = PLATFORM_RULES.get(platform)
        if rules is None:
            return {
                "is_valid": False,
                "score": 0,
                "issues": [{"severity": "high", "message": f"不支持的平台: {platform}"}],
                "passed": [],
            }

        issues: list[dict] = []
        passed: list[str] = []

        # --- 标题长度 ---
        title_len = len(title)
        max_title = rules["max_title_length"]
        if title_len > max_title:
            issues.append({
                "severity": "high",
                "message": f"标题长度 {title_len} 超过限制 {max_title}",
            })
        else:
            passed.append(f"标题长度合规（{title_len}/{max_title}）")

        # --- 内容长度 ---
        content_len = len(content)
        max_content = rules["max_content_length"]
        min_content = rules["min_content_length"]
        if content_len > max_content:
            issues.append({
                "severity": "high",
                "message": f"内容长度 {content_len} 超过限制 {max_content}",
            })
        elif min_content > 0 and content_len < min_content:
            issues.append({
                "severity": "medium",
                "message": f"内容长度 {content_len} 低于建议最低 {min_content}",
            })
        else:
            passed.append(f"内容长度合规（{content_len}/{max_content}）")

        # --- 平台特有规则 ---
        platform_specific = self._validate_platform_specific(content, title, platform)
        issues.extend(platform_specific["issues"])
        passed.extend(platform_specific["passed"])

        # --- 计算分数 ---
        total_checks = len(issues) + len(passed)
        if total_checks == 0:
            score = 100
        else:
            # high=扣15分, medium=扣8分, low=扣3分
            penalty = sum(
                15 if i["severity"] == "high" else 8 if i["severity"] == "medium" else 3
                for i in issues
            )
            score = max(0, 100 - penalty)

        return {
            "is_valid": len([i for i in issues if i["severity"] == "high"]) == 0,
            "score": score,
            "issues": issues,
            "passed": passed,
        }

    def _validate_platform_specific(
        self, content: str, title: str, platform: str
    ) -> dict:
        """平台特定规则校验"""
        issues: list[dict] = []
        passed: list[str] = []

        if platform == "wechat":
            # 诱导分享/关注
            if _INDUCING_PATTERNS.search(title) or _INDUCING_PATTERNS.search(content):
                issues.append({
                    "severity": "high",
                    "message": "包含诱导分享/关注语句",
                })
            else:
                passed.append("无诱导分享/关注语句")

            # 连续特殊符号
            if _CONSECUTIVE_SYMBOLS.search(title):
                issues.append({
                    "severity": "medium",
                    "message": "标题包含连续特殊符号",
                })
            else:
                passed.append("标题无连续特殊符号")

            # 外部链接
            if _EXTERNAL_LINK.search(content):
                issues.append({
                    "severity": "high",
                    "message": "正文包含外部链接（仅支持公众号链接和小程序）",
                })
            else:
                passed.append("无外部链接")

        elif platform == "zhihu":
            # 营销内容检测（简化）
            marketing_words = {"购买", "下单", "优惠价", "限时折扣", "点击购买"}
            found_marketing = marketing_words & set(content)
            if found_marketing:
                issues.append({
                    "severity": "medium",
                    "message": f"疑似营销用语: {', '.join(found_marketing)}",
                })
            else:
                passed.append("未检测到过度营销用语")

        elif platform == "xiaohongshu":
            # 字数建议
            content_len = len(content)
            if content_len > 800:
                issues.append({
                    "severity": "medium",
                    "message": f"正文建议300-800字，当前 {content_len} 字",
                })
            elif content_len < 300:
                issues.append({
                    "severity": "low",
                    "message": f"正文建议300-800字，当前仅 {content_len} 字",
                })
            else:
                passed.append(f"正文字数适宜（{content_len}字）")

            # 其他平台引流
            cross_platform_keywords = ["微信", "公众号", "抖音号", "微博"]
            found_cross = [p for p in cross_platform_keywords if p in content]
            if found_cross:
                issues.append({
                    "severity": "high",
                    "message": f"疑似其他平台引流: {', '.join(found_cross)}",
                })
            else:
                passed.append("未检测到其他平台引流信息")

        elif platform in ("baijiahao", "toutiao"):
            # 标题党检测
            found_clickbait = _CLICKBAIT_WORDS & set(title)
            if found_clickbait:
                issues.append({
                    "severity": "high",
                    "message": f"标题含标题党词汇: {', '.join(found_clickbait)}",
                })
            else:
                passed.append("标题无标题党词汇")

        elif platform == "douyin":
            # 水印检测
            if _WATERMARK_PATTERNS.search(content):
                issues.append({
                    "severity": "high",
                    "message": "内容包含其他平台水印信息",
                })
            else:
                passed.append("未检测到其他平台水印")

        return {"issues": issues, "passed": passed}

    def get_optimization_tips(self, platform: str) -> list[str]:
        """获取平台优化建议"""
        rules = PLATFORM_RULES.get(platform)
        if rules is None:
            return []
        return rules.get("seo_tips", [])
