"""Element Plus Select 组件关键字"""

from playwright.sync_api import Page, Locator
from typing import Optional, List, Union

from ..base_keyword import BaseKeyword
from ...reference import INFO


class ElSelectKeyword(BaseKeyword):
    """Element Plus Select 组件关键字

    处理 el-select 下拉选择器，包括单选、多选、可搜索等模式。
    """

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

    def el_select(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str,
        by: str = 'text'
    ) -> None:
        """Element Plus 下拉选择

        处理 teleport 到 body 的下拉面板。

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 选项值
            by: 选择方式 (text, value, index)
        """
        INFO(f"Element Plus 选择: {content}")

        # 点击触发下拉
        select = self.locator(targeting, element, index)
        select.click()

        # 等待下拉面板出现（teleport 到 body）
        dropdown = self.page.locator('.el-select-dropdown:visible, .el-popper:visible')
        dropdown.wait_for(state='visible', timeout=5000)

        # 等待动画完成
        self.page.wait_for_timeout(100)

        # 选择选项
        if by == 'text':
            option_loc = dropdown.locator(f'.el-select-dropdown__item:has-text("{content}")')
        elif by == 'value':
            option_loc = dropdown.locator(f'.el-select-dropdown__item[data-value="{content}"]')
        elif by == 'index':
            option_loc = dropdown.locator('.el-select-dropdown__item').nth(int(content))
        else:
            option_loc = dropdown.locator(f'.el-select-dropdown__item:has-text("{content}")')

        # 确保选项可见
        if option_loc.count() > 0:
            option_loc.first.scroll_into_view_if_needed()
            option_loc.first.click()
        else:
            INFO(f"未找到选项: {content}", "WARNING")

        # 等待下拉面板关闭
        try:
            dropdown.wait_for(state='hidden', timeout=3000)
        except Exception:
            # 如果面板没关闭，按 Escape 关闭
            self.page.keyboard.press('Escape')

    def el_select_multiple(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str
    ) -> None:
        """多选下拉

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 选项值（多个用逗号分隔）
        """
        options = [opt.strip() for opt in str(content).split(',')]
        INFO(f"Element Plus 多选: {options}")

        # 点击打开下拉
        select = self.locator(targeting, element, index)
        select.click()

        dropdown = self.page.locator('.el-select-dropdown:visible, .el-popper:visible')
        dropdown.wait_for(state='visible', timeout=5000)
        self.page.wait_for_timeout(100)

        # 逐个选择
        for opt in options:
            option_loc = dropdown.locator(f'.el-select-dropdown__item:has-text("{opt}")')
            if option_loc.count() > 0:
                option_loc.first.click()
                self.page.wait_for_timeout(100)

        # 点击外部关闭
        self.page.keyboard.press('Escape')

    def el_select_clear(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None
    ) -> None:
        """清除选择

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
        """
        INFO("清除 Select 选择")
        select = self.locator(targeting, element, index)

        # 悬停显示清除按钮
        select.hover()
        self.page.wait_for_timeout(200)

        # 点击清除按钮
        clear_btn = select.locator('.el-select__clear, .el-icon-circle-close')
        if clear_btn.is_visible():
            clear_btn.click()

    def el_select_search(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str,
        select_first: bool = True
    ) -> None:
        """可搜索下拉框

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 搜索关键词
            select_first: 是否选择第一个结果
        """
        INFO(f"搜索并选择: {content}")
        select = self.locator(targeting, element, index)

        # 点击打开
        select.click()
        self.page.wait_for_timeout(200)

        # 找到输入框并输入
        input_el = select.locator('.el-select__input, .el-input__inner')
        if input_el.count() > 0:
            input_el.first.fill(str(content))
            self.page.wait_for_timeout(300)  # 等待搜索

        # 选择结果
        if select_first:
            dropdown = self.page.locator('.el-select-dropdown:visible, .el-popper:visible')
            if dropdown.is_visible():
                first_option = dropdown.locator('.el-select-dropdown__item:not(.is-disabled)').first
                if first_option.is_visible():
                    first_option.click()

    def el_select_get_value(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None
    ) -> str:
        """获取当前选中值

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引

        Returns:
            str: 选中的值
        """
        select = self.locator(targeting, element, index)

        # 尝试获取选中的标签
        tags = select.locator('.el-select__tags .el-tag')
        if tags.count() > 0:
            # 多选模式
            values = [tag.text_content().strip() for tag in tags.all()]
            return ','.join(values)

        # 单选模式
        input_el = select.locator('.el-input__inner, .el-select__input')
        if input_el.count() > 0:
            value = input_el.first.get_attribute('value') or input_el.first.text_content()
            return (value or '').strip()

        return ''

    def el_select_assert(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str,
        mode: str = 'equals'
    ) -> bool:
        """断言选中值

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 期望值
            mode: 断言模式

        Returns:
            bool: 断言结果
        """
        actual = self.el_select_get_value(targeting, element, index)

        if mode == 'equals':
            result = actual == content
        elif mode == 'contains':
            result = content in actual
        else:
            result = actual == content

        INFO(f"Select 断言: '{actual}' {mode} '{content}' -> {result}")
        return result

    def el_select_option_count(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None
    ) -> int:
        """获取选项数量

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引

        Returns:
            int: 选项数量
        """
        select = self.locator(targeting, element, index)
        select.click()

        dropdown = self.page.locator('.el-select-dropdown:visible')
        dropdown.wait_for(state='visible', timeout=3000)

        count = dropdown.locator('.el-select-dropdown__item').count()

        self.page.keyboard.press('Escape')
        return count
