"""SEO 优化器.

提供关键词密度计算、可读性评分等 SEO 功能。
"""

from __future__ import annotations

import re
from dataclasses import dataclass
from typing import Any


@dataclass
class SEOResult:
    """SEO 优化结果."""

    score: float
    keyword_density: float
    readability_score: float
    title_optimization: dict[str, Any]
    meta_description: str
    suggestions: list[str]


class SEOOptimizer:
    """SEO 优化器."""

    def __init__(self) -> None:
        self.ideal_keyword_density = 1.5
        self.title_max_length = 60
        self.meta_max_length = 160

    def calculate_keyword_density(self, content: str, keyword: str) -> float:
        """计算关键词密度."""
        content_lower = content.lower()
        keyword_lower = keyword.lower()
        word_count = len(content_lower.split())
        keyword_count = content_lower.count(keyword_lower)
        if word_count == 0:
            return 0.0
        return (keyword_count / word_count) * 100

    def calculate_readability(self, content: str) -> float:
        """计算 Flesch-Kincaid 可读性评分."""
        sentences = [s.strip() for s in re.split(r"[.!?]+", content) if s.strip()]
        words = content.split()

        if not sentences or not words:
            return 0.0

        def count_syllables(word: str) -> int:
            word = word.lower()
            vowels = "aeiouy"
            syllables = 0
            prev_was_vowel = False
            for char in word:
                is_vowel = char in vowels
                if is_vowel and not prev_was_vowel:
                    syllables += 1
                prev_was_vowel = is_vowel
            if word.endswith("e"):
                syllables -= 1
            return max(1, syllables)

        total_syllables = sum(count_syllables(w) for w in words)
        avg_sentence_length = len(words) / len(sentences)
        avg_syllables_per_word = total_syllables / len(words)

        score = 206.835 - (1.015 * avg_sentence_length) - (84.6 * avg_syllables_per_word)
        return max(0, min(100, score))

    def optimize_title(self, title: str, keyword: str) -> dict[str, Any]:
        """优化标题."""
        score = 100.0
        if len(title) > self.title_max_length:
            score -= 20
        if keyword.lower() not in title.lower():
            score -= 30
        return {"original": title, "score": max(0, score), "length": len(title)}

    def generate_meta_description(self, content: str, keyword: str) -> str:
        """生成元描述."""
        desc = content[:150]
        if keyword.lower() not in desc.lower():
            desc = f"{keyword}: {desc}"
        return desc[: self.meta_max_length]

    def optimize(self, content: str, keyword: str, title: str) -> SEOResult:
        """执行完整 SEO 优化."""
        suggestions = []
        density = self.calculate_keyword_density(content, keyword)
        readability = self.calculate_readability(content)
        title_opt = self.optimize_title(title, keyword)

        if density < 1.0:
            suggestions.append(f"关键词密度偏低 ({density:.2f}%)")
        elif density > 3.0:
            suggestions.append(f"关键词密度过高 ({density:.2f}%)")

        if readability < 60:
            suggestions.append("可读性较低，建议使用更简单的词汇")

        # 计算综合得分：基于关键词密度、可读性、标题优化
        # 密度得分: 理想密度 1.5%, 在合理范围内 (0.5-5%) 不扣分
        if 0.5 <= density <= 5.0:
            density_score = 90.0  # 在合理范围内给高分
        else:
            density_score = max(0, 100 - abs(density - self.ideal_keyword_density) * 15)

        # 可读性得分: 直接使用可读性分数
        readability_score = readability

        # 标题得分
        title_score = title_opt["score"]

        # 内容长度惩罚：内容少于 50 个字符大幅扣分
        word_count = len(content.split())
        if word_count < 10:
            length_penalty = 50
        elif word_count < 50:
            length_penalty = 20
        else:
            length_penalty = 0

        # 综合得分 (权重: 密度20%, 可读性30%, 标题50%)
        score = (density_score * 0.2 + readability_score * 0.3 + title_score * 0.5) - length_penalty
        score = max(0, min(100, score))

        return SEOResult(
            score=round(score, 1),
            keyword_density=density,
            readability_score=readability,
            title_optimization=title_opt,
            meta_description=self.generate_meta_description(content, keyword),
            suggestions=suggestions,
        )
