"""
页面分析器和内容分析器
分析页面结构和内容
"""
import re
from typing import Dict, Any, List
from collections import Counter
from playwright.async_api import Page


class PageAnalyzer:
    """
    页面分析器
    分析页面结构和内容
    """

    def __init__(self, page: Page):
        self.page = page

    async def get_page_structure(self) -> Dict[str, Any]:
        """
        获取页面结构

        Returns:
            Dict: 页面结构信息
        """
        structure = await self.page.evaluate("""
            () => {
                const result = {
                    title: document.title,
                    url: location.href,
                    headings: [],
                    links: [],
                    images: [],
                    forms: [],
                    buttons: [],
                    inputs: [],
                };

                // 标题
                document.querySelectorAll('h1, h2, h3').forEach(h => {
                    result.headings.push({
                        tag: h.tagName,
                        text: h.textContent.trim().substring(0, 100),
                    });
                });

                // 链接
                document.querySelectorAll('a[href]').forEach(a => {
                    result.links.push({
                        text: a.textContent.trim().substring(0, 50),
                        href: a.href,
                    });
                });

                // 图片
                document.querySelectorAll('img[src]').forEach(img => {
                    result.images.push({
                        alt: img.alt || '',
                        src: img.src,
                    });
                });

                // 表单
                document.querySelectorAll('form').forEach(form => {
                    result.forms.push({
                        action: form.action,
                        method: form.method,
                        inputs: form.querySelectorAll('input, textarea, select').length,
                    });
                });

                // 按钮
                document.querySelectorAll('button, input[type="button"], input[type="submit"]').forEach(btn => {
                    result.buttons.push(btn.textContent.trim() || btn.value || '');
                });

                // 输入框
                document.querySelectorAll('input, textarea, select').forEach(input => {
                    result.inputs.push({
                        type: input.type || input.tagName.toLowerCase(),
                        name: input.name || input.id || '',
                        placeholder: input.placeholder || '',
                    });
                });

                return result;
            }
        """)

        return structure

    async def find_clickable_elements(self) -> List[Dict[str, str]]:
        """
        查找所有可点击元素

        Returns:
            List: 可点击元素列表
        """
        elements = await self.page.evaluate("""
            () => {
                const result = [];
                const selectors = [
                    'a[href]',
                    'button',
                    'input[type="button"]',
                    'input[type="submit"]',
                    '[role="button"]',
                    '[onclick]',
                    '[tabindex]',
                ];

                document.querySelectorAll(selectors.join(', ')).forEach(el => {
                    const rect = el.getBoundingClientRect();
                    if (rect.width > 0 && rect.height > 0) {
                        result.push({
                            tag: el.tagName,
                            text: el.textContent.trim().substring(0, 50),
                            id: el.id,
                            className: el.className,
                            selector: el.id ? '#' + el.id : (el.className ? '.' + el.className.split(' ')[0] : el.tagName.toLowerCase()),
                        });
                    }
                });

                return result;
            }
        """)

        return elements

    async def find_form_fields(self) -> List[Dict[str, str]]:
        """
        查找所有表单字段

        Returns:
            List: 表单字段列表
        """
        fields = await self.page.evaluate("""
            () => {
                const result = [];
                document.querySelectorAll('input, textarea, select').forEach(el => {
                    const label = document.querySelector('label[for="' + el.id + '"]');
                    result.push({
                        tag: el.tagName.toLowerCase(),
                        type: el.type || 'text',
                        name: el.name || '',
                        id: el.id || '',
                        placeholder: el.placeholder || '',
                        label: label ? label.textContent.trim() : '',
                        required: el.required,
                    });
                });
                return result;
            }
        """)

        return fields

    async def check_accessibility(self) -> List[Dict[str, str]]:
        """
        检查可访问性问题

        Returns:
            List: 问题列表
        """
        issues = await self.page.evaluate("""
            () => {
                const issues = [];

                // 图片缺少alt
                document.querySelectorAll('img:not([alt])').forEach(img => {
                    issues.push({
                        type: 'missing-alt',
                        element: 'img',
                        message: '图片缺少alt属性',
                        src: img.src,
                    });
                });

                // 输入框缺少label
                document.querySelectorAll('input:not([id]), textarea:not([id])').forEach(el => {
                    if (!el.getAttribute('aria-label')) {
                        issues.push({
                            type: 'missing-label',
                            element: el.tagName.toLowerCase(),
                            message: '输入框缺少标签',
                        });
                    }
                });

                // 空链接
                document.querySelectorAll('a[href=""], a:not([href])').forEach(a => {
                    issues.push({
                        type: 'empty-link',
                        element: 'a',
                        message: '链接没有目标',
                        text: a.textContent.trim(),
                    });
                });

                // 标题层级
                let lastLevel = 0;
                document.querySelectorAll('h1, h2, h3, h4, h5, h6').forEach(h => {
                    const level = parseInt(h.tagName[1]);
                    if (level - lastLevel > 1) {
                        issues.push({
                            type: 'heading-level',
                            element: h.tagName,
                            message: '标题层级跳跃',
                            text: h.textContent.trim().substring(0, 50),
                        });
                    }
                    lastLevel = level;
                });

                return issues;
            }
        """)

        return issues

    async def extract_text_content(self) -> str:
        """
        提取页面主要内容

        Returns:
            str: 主要文本内容
        """
        text = await self.page.evaluate("""
            () => {
                const clone = document.body.cloneNode(true);
                clone.querySelectorAll('script, style, nav, footer, aside').forEach(el => el.remove());
                return clone.textContent.replace(/\\s+/g, ' ').trim();
            }
        """)

        return text

    async def get_element_tree(self, max_depth: int = 3) -> Dict[str, Any]:
        """获取元素树结构"""
        tree = await self.page.evaluate(f"""
            () => {{
                function buildTree(el, depth) {{
                    if (depth > {max_depth}) return null;

                    const node = {{
                        tag: el.tagName.toLowerCase(),
                        id: el.id || '',
                        className: el.className || '',
                        children: []
                    }};

                    for (const child of el.children) {{
                        const childNode = buildTree(child, depth + 1);
                        if (childNode) node.children.push(childNode);
                    }}

                    return node;
                }}

                return buildTree(document.body, 0);
            }}
        """)

        return tree


class ContentAnalyzer:
    """
    内容分析器
    分析页面内容
    """

    def __init__(self, page: Page):
        self.page = page

    async def extract_keywords(self, top_n: int = 10) -> List[str]:
        """提取页面关键词"""
        text = await self.page.evaluate("() => document.body.textContent")

        words = re.findall(r'[\u4e00-\u9fa5]+|[a-zA-Z]+', text.lower())
        word_count = Counter(words)

        stop_words = {'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been',
                      '的', '是', '在', '了', '和', '与', '或', '也'}

        keywords = [
            word for word, count in word_count.most_common(50)
            if word not in stop_words and len(word) > 1
        ][:top_n]

        return keywords

    async def detect_language(self) -> str:
        """检测页面语言"""
        lang = await self.page.evaluate("""
            () => document.documentElement.lang || navigator.language || 'unknown'
        """)
        return lang

    async def get_sentiment(self) -> Dict[str, Any]:
        """分析页面情感（简单实现）"""
        text = await self.page.evaluate("() => document.body.textContent")

        positive_words = {'好', '优秀', '成功', '喜欢', '棒', 'great', 'good', 'excellent', 'success'}
        negative_words = {'坏', '失败', '错误', '问题', '差', 'bad', 'error', 'fail', 'problem'}

        text_lower = text.lower()

        positive_count = sum(1 for word in positive_words if word in text_lower)
        negative_count = sum(1 for word in negative_words if word in text_lower)

        if positive_count > negative_count:
            sentiment = 'positive'
        elif negative_count > positive_count:
            sentiment = 'negative'
        else:
            sentiment = 'neutral'

        return {
            'sentiment': sentiment,
            'positive_count': positive_count,
            'negative_count': negative_count,
        }

    async def extract_entities(self) -> Dict[str, List[str]]:
        """提取页面中的实体（简单实现）"""
        text = await self.page.evaluate("() => document.body.textContent")

        entities = {
            'emails': [],
            'phones': [],
            'urls': [],
        }

        # 提取邮箱
        emails = re.findall(r'[\w.-]+@[\w.-]+\.\w+', text)
        entities['emails'] = list(set(emails))

        # 提取电话
        phones = re.findall(r'\b\d{3}[-.]?\d{3}[-.]?\d{4}\b|\b1[3-9]\d{9}\b', text)
        entities['phones'] = list(set(phones))

        # 提取URL
        urls = re.findall(r'https?://[^\s<>"{}|\\^`\[\]]+', text)
        entities['urls'] = list(set(urls))

        return entities

    async def summarize(self, max_length: int = 200) -> str:
        """生成页面摘要"""
        text = await self.page.evaluate("""
            () => {
                const main = document.querySelector('main, article, .content, #content');
                if (main) return main.textContent.trim();
                return document.body.textContent.trim();
            }
        """)

        # 简单截取
        text = ' '.join(text.split())
        if len(text) > max_length:
            return text[:max_length] + '...'

        return text
