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

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 ElTreeKeyword(BaseKeyword):
    """Element Plus Tree 树形控件关键字

    处理树形控件的节点展开、选择、勾选等操作。
    """

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

    def el_tree_click_node(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str
    ) -> None:
        """点击树节点

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 节点文本或路径 (格式: "父节点/子节点")
        """
        INFO(f"点击树节点: {content}")

        tree = self.locator(targeting, element, index)

        if '/' in str(content):
            # 路径格式，逐级展开
            nodes = [n.strip() for n in str(content).split('/')]
            for i, node_text in enumerate(nodes):
                node = tree.locator(f'.el-tree-node:has(.el-tree-node__label:text("{node_text}"))')
                if node.count() > 0:
                    if i < len(nodes) - 1:
                        # 非最后一级，展开
                        expand_icon = node.first.locator('.el-tree-node__expand-icon')
                        if expand_icon.is_visible() and not node.first.locator('.is-expanded').count():
                            expand_icon.click()
                            self.page.wait_for_timeout(200)
                    else:
                        # 最后一级，点击
                        node.first.locator('.el-tree-node__content').click()
        else:
            # 直接匹配
            node = tree.locator(f'.el-tree-node__label:text("{content}")')
            node.first.click()

    def el_tree_expand_node(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str
    ) -> None:
        """展开树节点

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 节点文本
        """
        INFO(f"展开树节点: {content}")

        tree = self.locator(targeting, element, index)
        node = tree.locator(f'.el-tree-node:has(.el-tree-node__label:text("{content}"))')

        if node.count() > 0:
            expand_icon = node.first.locator('.el-tree-node__expand-icon')
            if expand_icon.is_visible():
                # 检查是否已展开
                if not node.first.locator('.is-expanded').count():
                    expand_icon.click()

    def el_tree_collapse_node(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str
    ) -> None:
        """折叠树节点

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 节点文本
        """
        INFO(f"折叠树节点: {content}")

        tree = self.locator(targeting, element, index)
        node = tree.locator(f'.el-tree-node:has(.el-tree-node__label:text("{content}"))')

        if node.count() > 0:
            expand_icon = node.first.locator('.el-tree-node__expand-icon')
            if expand_icon.is_visible():
                # 检查是否已展开
                if node.first.locator('.is-expanded').count():
                    expand_icon.click()

    def el_tree_check_node(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str,
        checked: bool = True
    ) -> None:
        """勾选树节点

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 节点文本
            checked: 是否勾选
        """
        INFO(f"{'勾选' if checked else '取消勾选'}树节点: {content}")

        tree = self.locator(targeting, element, index)
        node = tree.locator(f'.el-tree-node:has(.el-tree-node__label:text("{content}"))')

        if node.count() > 0:
            checkbox = node.first.locator('.el-checkbox')
            if checkbox.is_visible():
                is_checked = checkbox.locator('.is-checked').count() > 0

                if checked and not is_checked:
                    checkbox.click()
                elif not checked and is_checked:
                    checkbox.click()

    def el_tree_check_nodes(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str
    ) -> None:
        """勾选多个树节点

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 节点文本列表 (格式: "节点1,节点2,节点3")
        """
        nodes = [n.strip() for n in str(content).split(',')]
        INFO(f"勾选多个树节点: {nodes}")

        for node_text in nodes:
            self.el_tree_check_node(targeting, element, index, content=node_text, checked=True)

    def el_tree_expand_all(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None
    ) -> None:
        """展开所有节点

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
        """
        INFO("展开所有树节点")

        tree = self.locator(targeting, element, index)
        expand_icons = tree.locator('.el-tree-node:not(.is-expanded) .el-tree-node__expand-icon:not(.is-leaf)')

        # 从上到下依次展开
        while expand_icons.count() > 0:
            expand_icons.first.click()
            self.page.wait_for_timeout(100)
            expand_icons = tree.locator('.el-tree-node:not(.is-expanded) .el-tree-node__expand-icon:not(.is-leaf)')

    def el_tree_collapse_all(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None
    ) -> None:
        """折叠所有节点

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
        """
        INFO("折叠所有树节点")

        tree = self.locator(targeting, element, index)
        expanded = tree.locator('.el-tree-node.is-expanded .el-tree-node__expand-icon')

        # 从下到上依次折叠
        while expanded.count() > 0:
            expanded.last.click()
            self.page.wait_for_timeout(100)
            expanded = tree.locator('.el-tree-node.is-expanded .el-tree-node__expand-icon')

    def el_tree_search(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str,
        input_selector: str = '.el-input__inner'
    ) -> None:
        """搜索树节点

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 搜索关键词
            input_selector: 搜索输入框选择器
        """
        INFO(f"搜索树: {content}")

        tree = self.locator(targeting, element, index)

        # 查找关联的搜索框（可能在树组件外部）
        search_input = tree.locator(input_selector)
        if not search_input.is_visible():
            search_input = self.page.locator(input_selector).first

        search_input.fill(str(content))
        self.page.wait_for_timeout(300)

    def el_tree_get_checked_nodes(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str = None
    ) -> List[str]:
        """获取已勾选的节点

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 缓存键名

        Returns:
            List[str]: 已勾选节点的文本列表
        """
        tree = self.locator(targeting, element, index)
        checked_nodes = tree.locator('.el-tree-node .el-checkbox.is-checked')

        result = []
        for i in range(checked_nodes.count()):
            node = checked_nodes.nth(i)
            label = node.locator('~ .el-tree-node__label, + .el-tree-node__label')
            if label.count() > 0:
                text = label.first.text_content()
                if text:
                    result.append(text.strip())

        INFO(f"已勾选节点: {result}")

        if content:
            set_element_value(content, result)

        return result

    def el_tree_get_node_count(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None
    ) -> int:
        """获取节点总数

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

        Returns:
            int: 节点数量
        """
        tree = self.locator(targeting, element, index)
        count = tree.locator('.el-tree-node').count()
        INFO(f"树节点总数: {count}")
        return count

    def el_tree_assert_node_exists(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str
    ) -> bool:
        """断言节点存在

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 节点文本

        Returns:
            bool: 断言结果
        """
        tree = self.locator(targeting, element, index)
        node = tree.locator(f'.el-tree-node__label:text("{content}")')
        result = node.count() > 0

        INFO(f"节点存在断言: '{content}' -> {result}")
        return result

    def el_tree_assert_node_checked(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str,
        expected: bool = True
    ) -> bool:
        """断言节点勾选状态

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 节点文本
            expected: 期望的勾选状态

        Returns:
            bool: 断言结果
        """
        tree = self.locator(targeting, element, index)
        node = tree.locator(f'.el-tree-node:has(.el-tree-node__label:text("{content}"))')

        is_checked = False
        if node.count() > 0:
            checkbox = node.first.locator('.el-checkbox.is-checked')
            is_checked = checkbox.count() > 0

        result = is_checked == expected
        INFO(f"节点勾选断言: '{content}' checked={is_checked}, expected={expected} -> {result}")
        return result
