"""平台规则引擎单元测试"""
import pytest


# ---------------------------------------------------------------------------
# PlatformRuleEngine 测试
# ---------------------------------------------------------------------------

class TestPlatformRuleEngine:
    @pytest.fixture
    def engine(self):
        from app.services.distribution.platform_rules import PlatformRuleEngine
        return PlatformRuleEngine()

    def test_get_platforms_returns_all(self, engine):
        """返回所有 6 个平台"""
        platforms = engine.get_platforms()
        assert len(platforms) == 6
        ids = {p["id"] for p in platforms}
        assert ids == {"wechat", "zhihu", "xiaohongshu", "baijiahao", "douyin", "toutiao"}

    def test_get_platforms_fields(self, engine):
        """每个平台包含必要字段"""
        platforms = engine.get_platforms()
        required_fields = {"id", "name", "icon", "max_title_length", "max_content_length",
                           "min_content_length", "supported_media", "max_images"}
        for p in platforms:
            assert required_fields.issubset(p.keys())

    def test_validate_title_too_long(self, engine):
        """标题超长返回 high severity issue"""
        # 微信公众号标题上限 22 字
        title = "这个标题非常非常非常非常非常非常非常长超过了微信的限制"
        content = "这是正文内容，字数足够满足最低要求。" * 30
        result = engine.validate_content(content, title, "wechat")

        assert result["is_valid"] is False
        issues = result["issues"]
        high_issues = [i for i in issues if i["severity"] == "high"]
        assert any("标题" in i["message"] for i in high_issues)

    def test_validate_content_too_short(self, engine):
        """内容过短返回 medium severity issue"""
        title = "正常标题"
        content = "短内容"  # 远少于 300 字最低要求
        result = engine.validate_content(content, title, "wechat")

        issues = result["issues"]
        assert any("内容长度" in i["message"] for i in issues)

    def test_validate_valid_content(self, engine):
        """合规内容 score >= 90"""
        title = "合规标题测试"  # 长度在 22 字以内
        content = "这是符合要求的内容。" * 50  # 足够长度，无违规
        result = engine.validate_content(content, title, "wechat")

        assert result["score"] >= 90

    def test_validate_unknown_platform(self, engine):
        """未知平台返回 is_valid=False"""
        result = engine.validate_content("content", "title", "unknown_platform_xyz")
        assert result["is_valid"] is False
        assert result["score"] == 0

    def test_validate_wechat_external_link(self, engine):
        """微信正文包含外部链接返回 high severity issue"""
        title = "标题"
        content = "正文内容 " * 50 + " 点击 https://example.com/test 查看"
        result = engine.validate_content(content, title, "wechat")

        issues = result["issues"]
        assert any("外部链接" in i["message"] for i in issues)

    def test_validate_wechat_consecutive_symbols_in_title(self, engine):
        """微信标题含连续特殊符号返回 medium issue"""
        title = "惊喜!!!三连"
        content = "正文内容，满足最低字数要求。" * 30
        result = engine.validate_content(content, title, "wechat")

        issues = result["issues"]
        assert any("连续特殊符号" in i["message"] for i in issues)

    def test_get_optimization_tips_returns_list(self, engine):
        """get_optimization_tips 返回非空列表"""
        tips = engine.get_optimization_tips("wechat")
        assert isinstance(tips, list)
        assert len(tips) > 0

    def test_get_optimization_tips_unknown_platform(self, engine):
        """未知平台返回空列表"""
        tips = engine.get_optimization_tips("unknown_xyz")
        assert tips == []


# ---------------------------------------------------------------------------
# ContentFormatter 测试
# ---------------------------------------------------------------------------

class TestContentFormatter:
    @pytest.fixture
    def formatter(self):
        from app.services.distribution.formatter import ContentFormatter
        return ContentFormatter()

    def test_formatter_xiaohongshu_strips_markdown(self, formatter):
        """小红书格式：移除 Markdown 标记"""
        md_content = "# 标题\n\n**加粗内容**\n\n[链接文本](http://example.com)"
        result = formatter.format_for_platform(md_content, "xiaohongshu")

        assert "**" not in result
        assert "#" not in result or result.strip().startswith("#") is False
        assert "http://example.com" not in result

    def test_formatter_wechat_removes_links(self, formatter):
        """微信格式：去除非公众号外链，保留链接文本"""
        content = "请访问 [示例网站](https://external-site.com/page) 了解详情"
        result = formatter.format_for_platform(content, "wechat")

        # 外部链接被移除，但文本保留
        assert "https://external-site.com" not in result
        assert "示例网站" in result

    def test_formatter_wechat_converts_headers(self, formatter):
        """微信格式：Markdown 标题转 HTML"""
        content = "## 二级标题\n\n正文内容"
        result = formatter.format_for_platform(content, "wechat")

        assert "<h2>" in result
        assert "二级标题" in result

    def test_formatter_zhihu_keeps_markdown(self, formatter):
        """知乎格式：保留 Markdown 结构"""
        content = "## 知乎标题\n\n**加粗内容**\n\n`代码示例`"
        result = formatter.format_for_platform(content, "zhihu")

        # 知乎支持 Markdown，应保留
        assert "**加粗内容**" in result

    def test_formatter_default_strips_markdown(self, formatter):
        """默认格式：清理 Markdown 为纯文本"""
        content = "# 标题\n\n**加粗**\n\n[链接](http://test.com)"
        result = formatter.format_for_platform(content, "unknown_platform")

        assert "#" not in result.split("\n")[0]  # 标题标记被移除
        assert "**" not in result
        assert "http://test.com" not in result

    def test_formatter_xiaohongshu_tags_moved_to_end(self, formatter):
        """小红书格式：话题标签移到文末"""
        content = "正文内容 #话题1 更多内容 #话题2"
        result = formatter.format_for_platform(content, "xiaohongshu")

        lines = result.strip().split("\n")
        last_line = lines[-1]
        # 最后一行包含标签
        assert "#话题1" in last_line or "#话题2" in last_line

    def test_formatter_wechat_bold_to_strong(self, formatter):
        """微信格式：**加粗** 转为 <strong>"""
        content = "这是**重要内容**需要加粗"
        result = formatter.format_for_platform(content, "wechat")

        assert "<strong>重要内容</strong>" in result
