"""
元素快捷定位 Mixin

提供极简语法的元素定位能力。
"""
from typing import Optional, TYPE_CHECKING

if TYPE_CHECKING:
    from playwright.async_api import Page
    from ...element import Element


class ElementLocatorMixin:
    """
    元素快捷定位功能

    支持 browser('selector') 语法直接定位元素。
    """

    # 由其他 mixin 提供的属性
    _tabs: dict
    _current_tab: Optional[str]
    config: "Config"

    @property
    def page(self) -> "Page":
        """获取当前标签页的 Page 对象"""
        return self.get_tab().page

    def __call__(self, selector: str) -> "Element":
        """
        极简语法定位元素

        自动检测选择器类型（CSS/XPath/文本等）并返回 Element 代理对象。

        Args:
            selector: 元素选择器，支持：
                - CSS 选择器: 'button.submit', 'div.container > p'
                - XPath: '//div[@id="x"]', 'xpath=//button'
                - 文本: 'text=登录', 't=提交'
                - 角色选择器: 'role=button', 'r=link'
                - 测试ID: 'test-id=submit-btn'

        Returns:
            Element: 元素代理对象，支持链式调用

        Example:
            # CSS 选择器
            await browser('button.submit').click()

            # XPath
            await browser('//div[@id="header"]').text

            # 文本匹配
            await browser('text=登录').click()

            # 链式调用
            await browser('input.username').fill('admin').press('Enter')

            # 相对定位
            card = browser('div.card')
            await card.child('button').click()
        """
        from ...element import Element

        page = self.page
        locator = self._detect_selector(page, selector)

        return Element(locator, page, selector)

    def _detect_selector(self, page: "Page", selector: str) -> "Locator":
        """
        自动检测选择器类型并返回 Locator

        Args:
            page: Page 对象
            selector: 选择器字符串

        Returns:
            Locator: Playwright Locator 对象
        """
        # 1. 检测显式前缀
        if selector.startswith("xpath=") or selector.startswith("xp="):
            return page.locator(f"xpath={selector.split('=', 1)[1]}")

        if selector.startswith("text=") or selector.startswith("t="):
            text = selector.split("=", 1)[1]
            return page.get_by_text(text)

        if selector.startswith("role=") or selector.startswith("r="):
            parts = selector.split("=", 1)[1].split(",", 1)
            role = parts[0].strip()
            name = parts[1].strip() if len(parts) > 1 else None
            return page.get_by_role(role, name=name)

        if selector.startswith("placeholder=") or selector.startswith("ph="):
            text = selector.split("=", 1)[1]
            return page.get_by_placeholder(text)

        if selector.startswith("label=") or selector.startswith("l="):
            text = selector.split("=", 1)[1]
            return page.get_by_label(text)

        if selector.startswith("test-id=") or selector.startswith("tid="):
            test_id = selector.split("=", 1)[1]
            return page.get_by_test_id(test_id)

        if selector.startswith("alt="):
            text = selector.split("=", 1)[1]
            return page.get_by_alt_text(text)

        if selector.startswith("title="):
            text = selector.split("=", 1)[1]
            return page.get_by_title(text)

        # 2. 检测 XPath 格式（以 // 或 ./ 开头）
        if selector.startswith("//") or selector.startswith("./"):
            return page.locator(f"xpath={selector}")

        # 3. 检测 Playwright 文本选择器格式
        if selector.startswith("text="):
            return page.locator(selector)

        # 4. 默认使用 CSS 选择器
        return page.locator(selector)

    def find(self, selector: str) -> "Element":
        """
        查找元素（等同于 __call__）

        Args:
            selector: 元素选择器

        Returns:
            Element: 元素代理对象

        Example:
            button = browser.find('button.submit')
        """
        return self(selector)

    def find_all(self, selector: str) -> "Element":
        """
        查找所有匹配元素

        Args:
            selector: 元素选择器

        Returns:
            Element: 元素列表代理对象

        Example:
            items = browser.find_all('li.item')
            count = await items.count()
            async for item in items:
                print(await item.text)
        """
        from ...element import ElementList

        page = self.page
        locator = self._detect_selector(page, selector)

        return ElementList(locator, page, selector)

    # ==================== 快捷定位方法 ====================

    def by_text(self, text: str, exact: bool = False) -> "Element":
        """
        通过文本定位元素

        Args:
            text: 文本内容
            exact: 是否精确匹配

        Returns:
            Element: 元素代理对象

        Example:
            await browser.by_text('登录').click()
        """
        from ...element import Element

        page = self.page
        locator = page.get_by_text(text, exact=exact)
        return Element(locator, page, f"text={text}")

    def by_role(self, role: str, name: Optional[str] = None) -> "Element":
        """
        通过 ARIA 角色定位元素

        Args:
            role: ARIA 角色 (button, link, textbox, etc.)
            name: 可访问名称

        Returns:
            Element: 元素代理对象

        Example:
            await browser.by_role('button', name='提交').click()
        """
        from ...element import Element

        page = self.page
        locator = page.get_by_role(role, name=name)
        return Element(locator, page, f"role={role}")

    def by_label(self, text: str) -> "Element":
        """
        通过标签文本定位元素

        Args:
            text: 标签文本

        Returns:
            Element: 元素代理对象

        Example:
            await browser.by_label('用户名').fill('admin')
        """
        from ...element import Element

        page = self.page
        locator = page.get_by_label(text)
        return Element(locator, page, f"label={text}")

    def by_placeholder(self, text: str) -> "Element":
        """
        通过占位符定位元素

        Args:
            text: 占位符文本

        Returns:
            Element: 元素代理对象

        Example:
            await browser.by_placeholder('请输入用户名').fill('admin')
        """
        from ...element import Element

        page = self.page
        locator = page.get_by_placeholder(text)
        return Element(locator, page, f"placeholder={text}")

    def by_test_id(self, test_id: str) -> "Element":
        """
        通过测试ID定位元素

        Args:
            test_id: 测试ID

        Returns:
            Element: 元素代理对象

        Example:
            await browser.by_test_id('submit-btn').click()
        """
        from ...element import Element

        page = self.page
        locator = page.get_by_test_id(test_id)
        return Element(locator, page, f"test-id={test_id}")

    def by_xpath(self, xpath: str) -> "Element":
        """
        通过 XPath 定位元素

        Args:
            xpath: XPath 表达式

        Returns:
            Element: 元素代理对象

        Example:
            await browser.by_xpath('//div[@id="header"]/h1').text
        """
        from ...element import Element

        page = self.page
        locator = page.locator(f"xpath={xpath}")
        return Element(locator, page, xpath)

    def by_css(self, selector: str) -> "Element":
        """
        通过 CSS 选择器定位元素

        Args:
            selector: CSS 选择器

        Returns:
            Element: 元素代理对象

        Example:
            await browser.by_css('button.submit').click()
        """
        from ...element import Element

        page = self.page
        locator = page.locator(selector)
        return Element(locator, page, selector)
