"""
AI 辅助主类
整合智能查找、分析、修复等功能
支持 LLM 混合模式
"""
import re
import asyncio
from datetime import datetime
from typing import Optional, List, Dict, Any, Callable

from playwright.async_api import Page
from loguru import logger

from .types import AIConfig, SelectorSuggestion, ErrorDiagnosis, CodeSuggestion
from .finder import SmartElementFinder
from .analyzer import PageAnalyzer, ContentAnalyzer
from .healer import AutoHealer
from .engine.hybrid_engine import HybridEngine


class AIHelper:
    """
    AI 辅助工具
    整合智能查找、分析、修复等功能
    支持规则引擎和 LLM 混合模式
    """

    def __init__(self, page: Page, config: Optional[AIConfig] = None):
        self.page = page
        self.config = config or AIConfig()

        # 初始化子模块
        self._finder = SmartElementFinder(page)
        self._analyzer = PageAnalyzer(page)
        self._healer = AutoHealer(page)
        self._content = ContentAnalyzer(page)

        # 初始化混合引擎
        self._engine = HybridEngine(page, self.config)

        # 缓存
        self._selector_cache: Dict[str, str] = {}
        self._error_history: List[Dict] = []

    # ==================== 智能选择器 ====================

    async def suggest_selectors(
        self,
        description: str,
        element_type: Optional[str] = None,
    ) -> List[SelectorSuggestion]:
        """
        根据描述建议选择器

        Args:
            description: 元素描述
            element_type: 元素类型 (button, input, link 等)

        Returns:
            List[SelectorSuggestion]: 选择器建议列表
        """
        return await self._engine.suggest_selectors(description, element_type)

    # ==================== 错误诊断 ====================

    async def diagnose_error(
        self,
        error: Exception,
        context: Optional[Dict] = None,
    ) -> ErrorDiagnosis:
        """
        诊断错误并提供解决方案

        Args:
            error: 错误对象
            context: 上下文信息

        Returns:
            ErrorDiagnosis: 诊断结果
        """
        return await self._engine.diagnose_error(error, context)

    # ==================== 代码生成 ====================

    async def generate_test_code(
        self,
        scenario: str,
        include_assertions: bool = True,
    ) -> CodeSuggestion:
        """
        根据场景生成测试代码

        Args:
            scenario: 测试场景描述
            include_assertions: 是否包含断言

        Returns:
            CodeSuggestion: 代码建议
        """
        return await self._engine.generate_test_code(scenario, include_assertions)

    # ==================== 自然语言操作 ====================

    async def execute_natural_command(self, command: str) -> bool:
        """
        执行自然语言命令

        Args:
            command: 自然语言命令

        Returns:
            bool: 是否执行成功
        """
        command_lower = command.lower()

        # 点击操作
        if '点击' in command or 'click' in command_lower:
            match = re.search(r'["\']?([^"\']+?)["\']', command)
            if match:
                target = match.group(1)
                locator = await self._finder.guess_element(target)
                if locator:
                    await locator.click()
                    return True

        # 输入操作
        elif '输入' in command or '填写' in command or 'type' in command_lower:
            matches = re.findall(r'["\']([^"\']+)["\']', command)
            if len(matches) >= 2:
                selector, value = matches[0], matches[1]
                locator = await self._finder.guess_element(selector)
                if locator:
                    await locator.fill(value)
                    return True

        # 导航操作
        elif '打开' in command or '访问' in command or 'goto' in command_lower:
            match = re.search(r'https?://\S+', command)
            if match:
                await self.page.goto(match.group(0))
                return True

        return False

    # ==================== 智能修复 ====================

    async def heal_and_retry(
        self,
        selector: str,
        action: Callable,
        max_attempts: int = 3,
    ) -> bool:
        """
        智能修复并重试

        Args:
            selector: 原始选择器
            action: 要执行的操作
            max_attempts: 最大尝试次数

        Returns:
            bool: 是否成功
        """
        for attempt in range(max_attempts):
            try:
                await action()
                return True

            except Exception as e:
                logger.warning(f"尝试 {attempt + 1} 失败: {e}")

                # 尝试修复选择器
                healed = await self._healer.heal_selector(f"auto_{attempt}", selector)
                if healed:
                    selector = healed

                # 等待后重试
                await asyncio.sleep(1)

        return False

    # ==================== 便捷访问 ====================

    @property
    def finder(self) -> SmartElementFinder:
        """获取元素查找器"""
        return self._finder

    @property
    def analyzer(self) -> PageAnalyzer:
        """获取页面分析器"""
        return self._analyzer

    @property
    def healer(self) -> AutoHealer:
        """获取自动修复器"""
        return self._healer

    @property
    def content(self) -> ContentAnalyzer:
        """获取内容分析器"""
        return self._content

    @property
    def engine(self) -> HybridEngine:
        """获取混合引擎"""
        return self._engine


def create_ai_helper(page: Page, config: Optional[AIConfig] = None) -> AIHelper:
    """创建 AI 辅助工具实例"""
    return AIHelper(page, config)
