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

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

from ..base_keyword import BaseKeyword
from ...reference import INFO, set_element_value


class ElCascaderKeyword(BaseKeyword):
    """Element Plus Cascader 级联选择器关键字

    处理级联选择器的多级选择、搜索等操作。
    """

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

    def el_cascader(
        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"级联选择: {options}")

        cascader = self.locator(targeting, element, index)
        cascader.click()

        # 等待面板出现
        panel = self.page.locator('.el-cascader-panel:visible, .el-cascader__dropdown:visible')
        panel.wait_for(state='visible', timeout=5000)

        # 逐级选择
        for i, opt in enumerate(options):
            # 找到当前级别的菜单
            menus = panel.locator('.el-cascader-menu')
            if menus.count() > i:
                menu = menus.nth(i)
                node = menu.locator(f'.el-cascader-node:has-text("{opt}")')
                if node.count() > 0:
                    node.first.click()
                    self.page.wait_for_timeout(200)

        # 关闭面板
        self.page.keyboard.press('Escape')

    def el_cascader_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}")

        cascader = self.locator(targeting, element, index)
        cascader.click()

        # 输入搜索
        input_el = cascader.locator('.el-input__inner')
        input_el.fill(str(content))
        self.page.wait_for_timeout(300)

        # 选择结果
        if select_first:
            suggestion = self.page.locator('.el-cascader__suggestion-panel:visible, .el-cascader-panel:visible')
            if suggestion.is_visible():
                first_item = suggestion.locator('.el-cascader__suggestion-item, .el-cascader-node').first
                if first_item.is_visible():
                    first_item.click()

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

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
        """
        INFO("清除级联选择")

        cascader = self.locator(targeting, element, index)
        cascader.hover()
        self.page.wait_for_timeout(200)

        clear_btn = cascader.locator('.el-cascader__clear-icon, .el-icon-circle-close')
        if clear_btn.is_visible():
            clear_btn.click()

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

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

        Returns:
            str: 选中的值（路径格式）
        """
        cascader = self.locator(targeting, element, index)

        # 尝试获取标签
        tags = cascader.locator('.el-cascader__tags .el-tag')
        if tags.count() > 0:
            values = [tag.text_content().strip() for tag in tags.all()]
            return ' / '.join(values)

        # 获取输入框值
        input_el = cascader.locator('.el-input__inner')
        value = input_el.get_attribute('value') or input_el.text_content()
        return (value or '').strip()

    def el_cascader_expand(
        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"展开级联: {options}")

        cascader = self.locator(targeting, element, index)
        cascader.click()

        panel = self.page.locator('.el-cascader-panel:visible')
        panel.wait_for(state='visible', timeout=5000)

        # 逐级展开（不选择叶子节点）
        for i, opt in enumerate(options):
            menus = panel.locator('.el-cascader-menu')
            if menus.count() > i:
                menu = menus.nth(i)
                # 悬停展开
                node = menu.locator(f'.el-cascader-node:has-text("{opt}")')
                if node.count() > 0:
                    node.first.hover()
                    self.page.wait_for_timeout(200)

    def el_cascader_select_multiple(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str
    ) -> None:
        """多选级联

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 多个路径 (格式: "一级/二级,一级/三级")
        """
        paths = [path.strip() for path in str(content).split(',')]
        INFO(f"级联多选: {paths}")

        cascader = self.locator(targeting, element, index)
        cascader.click()

        panel = self.page.locator('.el-cascader-panel:visible')
        panel.wait_for(state='visible', timeout=5000)

        for path in paths:
            options = [opt.strip() for opt in path.split('/')]

            # 逐级选择
            for i, opt in enumerate(options):
                menus = panel.locator('.el-cascader-menu')
                if menus.count() > i:
                    menu = menus.nth(i)
                    node = menu.locator(f'.el-cascader-node:has-text("{opt}")')
                    if node.count() > 0:
                        # 如果是最后一级，点击复选框
                        if i == len(options) - 1:
                            checkbox = node.first.locator('.el-checkbox')
                            if checkbox.count() > 0:
                                checkbox.click()
                            else:
                                node.first.click()
                        else:
                            node.first.click()
                        self.page.wait_for_timeout(200)

        # 关闭面板
        self.page.keyboard.press('Escape')

    def el_cascader_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_cascader_get_value(targeting, element, index)

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

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