"""
智能元素查找器
使用启发式方法智能定位元素
"""
from typing import Optional, Any
from playwright.async_api import Page
from loguru import logger


class SmartElementFinder:
    """
    智能元素查找器
    使用启发式方法智能定位元素
    """

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

    async def find_by_text(self, text: str, fuzzy: bool = True) -> Optional[Any]:
        """
        通过文本查找元素

        Args:
            text: 文本内容
            fuzzy: 是否模糊匹配

        Returns:
            Locator: 元素定位器
        """
        if fuzzy:
            locator = self.page.get_by_text(text, exact=False)
        else:
            locator = self.page.get_by_text(text, exact=True)

        count = await locator.count()
        if count > 0:
            logger.info(f"找到元素: text='{text}', count={count}")
            return locator.first

        return None

    async def find_button(self, text: str = None, icon: str = None) -> Optional[Any]:
        """
        智能查找按钮

        Args:
            text: 按钮文本
            icon: 图标类名

        Returns:
            Locator: 按钮定位器
        """
        strategies = []

        if text:
            strategies.extend([
                f"button:has-text('{text}')",
                f"input[type='button'][value*='{text}']",
                f"input[type='submit'][value*='{text}']",
                f"a:has-text('{text}')",
                f"[role='button']:has-text('{text}')",
                f"[onclick]:has-text('{text}')",
            ])

        for selector in strategies:
            try:
                locator = self.page.locator(selector)
                if await locator.count() > 0:
                    logger.info(f"找到按钮: {selector}")
                    return locator.first
            except:
                continue

        return None

    async def find_input(
        self,
        label: str = None,
        placeholder: str = None,
        name: str = None,
    ) -> Optional[Any]:
        """
        智能查找输入框

        Args:
            label: 标签文本
            placeholder: 占位符
            name: name属性

        Returns:
            Locator: 输入框定位器
        """
        if label:
            locator = self.page.get_by_label(label)
            if await locator.count() > 0:
                return locator.first

        if placeholder:
            locator = self.page.get_by_placeholder(placeholder)
            if await locator.count() > 0:
                return locator.first

        if name:
            strategies = [
                f"input[name='{name}']",
                f"textarea[name='{name}']",
                f"select[name='{name}']",
                f"[name='{name}']",
            ]
            for selector in strategies:
                locator = self.page.locator(selector)
                if await locator.count() > 0:
                    return locator.first

        return None

    async def find_link(self, text: str = None, href: str = None) -> Optional[Any]:
        """
        智能查找链接

        Args:
            text: 链接文本
            href: 链接地址

        Returns:
            Locator: 链接定位器
        """
        if text:
            locator = self.page.get_by_role("link", name=text)
            if await locator.count() > 0:
                return locator.first

        if href:
            locator = self.page.locator(f"a[href*='{href}']")
            if await locator.count() > 0:
                return locator.first

        return None

    async def find_image(self, alt: str = None, src: str = None) -> Optional[Any]:
        """
        智能查找图片

        Args:
            alt: alt文本
            src: 图片地址

        Returns:
            Locator: 图片定位器
        """
        if alt:
            locator = self.page.get_by_alt_text(alt)
            if await locator.count() > 0:
                return locator.first

        if src:
            locator = self.page.locator(f"img[src*='{src}']")
            if await locator.count() > 0:
                return locator.first

        return None

    async def find_select(self, label: str = None, name: str = None) -> Optional[Any]:
        """
        智能查找下拉框

        Args:
            label: 标签文本
            name: name属性

        Returns:
            Locator: 下拉框定位器
        """
        if label:
            locator = self.page.get_by_label(label)
            if await locator.count() > 0:
                return locator.first

        if name:
            locator = self.page.locator(f"select[name='{name}']")
            if await locator.count() > 0:
                return locator.first

        return None

    async def find_checkbox(self, label: str = None, name: str = None) -> Optional[Any]:
        """
        智能查找复选框

        Args:
            label: 标签文本
            name: name属性

        Returns:
            Locator: 复选框定位器
        """
        if label:
            locator = self.page.get_by_label(label)
            if await locator.count() > 0:
                return locator.first

        if name:
            locator = self.page.locator(f"input[type='checkbox'][name='{name}']")
            if await locator.count() > 0:
                return locator.first

        return None

    async def guess_element(self, description: str) -> Optional[Any]:
        """
        根据描述猜测元素

        Args:
            description: 元素描述

        Returns:
            Locator: 元素定位器
        """
        desc_lower = description.lower()

        # 按钮相关
        if any(word in desc_lower for word in ['按钮', 'button', '点击', 'click']):
            return await self.find_button(text=description)

        # 输入框相关
        if any(word in desc_lower for word in ['输入', 'input', '文本框', '填写']):
            return await self.find_input(placeholder=description)

        # 链接相关
        if any(word in desc_lower for word in ['链接', 'link', '跳转']):
            return await self.find_link(text=description)

        # 图片相关
        if any(word in desc_lower for word in ['图片', 'image', 'img', '图标']):
            return await self.find_image(alt=description)

        # 下拉框相关
        if any(word in desc_lower for word in ['下拉', 'select', '选择']):
            return await self.find_select(label=description)

        # 复选框相关
        if any(word in desc_lower for word in ['复选', 'checkbox', '勾选']):
            return await self.find_checkbox(label=description)

        # 通用文本查找
        return await self.find_by_text(description)

    async def find_all_visible(self, selector: str) -> list:
        """查找所有可见元素"""
        locator = self.page.locator(selector)
        count = await locator.count()
        visible = []

        for i in range(count):
            el = locator.nth(i)
            if await el.is_visible():
                visible.append(el)

        return visible
