"""GEO 优化器.

提供生成式引擎优化功能。
"""

from __future__ import annotations

import re
from dataclasses import dataclass


@dataclass
class GEOResult:
    """GEO 优化结果."""

    score: float
    entity_density: float
    semantic_completeness: float
    question_coverage: float
    ai_summary: str
    suggestions: list[str]


class GEOOptimizer:
    """GEO (生成式引擎优化) 优化器."""

    def __init__(self) -> None:
        self.question_patterns = [
            r"什么是\s+(\w+)",
            r"如何\s+(\w+)",
            r"为什么\s+(\w+)",
        ]

    def extract_entities(self, content: str) -> set[str]:
        """提取内容中的实体."""
        proper_nouns = re.findall(r"\b[A-Z][a-zA-Z]*(?:\s+[A-Z][a-zA-Z]*)*\b", content)
        return set(proper_nouns)

    def calculate_entity_density(self, content: str) -> float:
        """计算实体密度."""
        entities = self.extract_entities(content)
        word_count = len(content.split())
        if word_count == 0:
            return 0.0
        return (len(entities) / word_count) * 100

    def calculate_semantic_completeness(self, content: str) -> float:
        """计算语义完整性."""
        score = 100.0
        if not re.search(r"##?\s+", content):
            score -= 15
        if not re.search(r"\d+\.\s+", content):
            score -= 15
        paragraphs = [p for p in content.split("\n\n") if len(p) > 50]
        if len(paragraphs) < 3:
            score -= 20
        return max(0, score)

    def optimize(self, content: str, target_questions: list[str] | None = None) -> GEOResult:
        """执行 GEO 优化分析."""
        suggestions = []
        entity_density = self.calculate_entity_density(content)
        semantic_score = self.calculate_semantic_completeness(content)

        if entity_density < 5.0:
            suggestions.append("实体密度偏低")

        score = entity_density * 3 + semantic_score * 0.4

        return GEOResult(
            score=min(100, score),
            entity_density=entity_density,
            semantic_completeness=semantic_score,
            question_coverage=100.0,
            ai_summary=content[:200] + "...",
            suggestions=suggestions,
        )
