"""
    Drissionpage-mcp中纯html的功能
"""
import os
from typing import Any

from fastmcp import FastMCP

from tools.tools import dp_mcp_message_pack
from DrissionPage.errors import NoRectError


def register_click_action(mcp: FastMCP, browser_manager):
    @mcp.tool(name="click_action",
              description="尝试点击tab页中的元素，返回元素是否可以被点击，以及是否点击成功。"
                          "其中target_element_index默认为0，当传入的Selector可以定位到多个元素时，需要传入target_element_index指定具体点击目标 ")
    async def click_action(browser_port: int, tab_id: str, css_selector: str, target_element_index: int = 0) -> dict[
        str, Any]:
        _browser = browser_manager.get_browser(browser_port)
        target_tab = _browser.get_tab(tab_id)
        css_selector = css_selector
        if "css:" not in css_selector:
            css_selector = "css:" + css_selector
        target_eles = target_tab.eles(css_selector)
        target_element = target_eles[target_element_index]
        element_clickable = target_element.states.is_clickable
        has_rect = False
        is_covered = True
        try:
            has_rect = target_element.states.has_rect
            is_covered = target_element.states.is_covered
            click_success = not is_covered
            if not is_covered:
                click_success = target_element.click()
                click_success = click_success is not False
        except NoRectError:
            has_rect = False
            click_success = False
        except Exception as e:
            click_success = False
        index_message = ""
        if target_element_index > 0:
            index_message = f"【target_element_index={target_element_index}】"
        if element_clickable:
            message = f"tab页:【{tab_id}】点击【Selector={css_selector}】{index_message}的元素 {'成功' if click_success else '失败'} 了"
        else:
            message = f"tab页:【{tab_id}】中【Selector={css_selector}】{index_message}的元素不可被点击"
        if has_rect:
            message += "，元素没有大小和位置信息"
        if has_rect and is_covered:
            message += "，元素被遮挡了"
        return dp_mcp_message_pack(
            message=message,
            browser_port=browser_port,
            tab_id=tab_id,
            css_selector=css_selector,
            element_clickable=element_clickable,
            click_success=click_success,
            extra_message="点击成功，页面可能有更新，请重新获取页面html，并重新分析页面Selector" if element_clickable and click_success else ""
        )


def register_scroll_action(mcp: FastMCP, browser_manager):
    @mcp.tool(name="scroll_action", description="尝试滚动tab页"
                                                "forward参数是滚动的方向：down、up、left、right"
                                                "pixel参数是滚动的像素值，默认为None。"
                                                "当forward为down且pixel为None，则将页面滚动到垂直中间位置，水平位置不变"
                                                "当forward为up且pixel为None，则将页面滚动到顶部，水平位置不变"
                                                "当forward为left且pixel为None，则将页面滚动到最左边，垂直位置不变"
                                                "当forward为right且pixel为None，则将页面滚动到最右边，垂直位置不变")
    async def scroll_action(browser_port: int, tab_id: str, forward: str = "down", pixel: int = None) -> dict[str, Any]:
        _browser = browser_manager.get_browser(browser_port)
        target_tab = _browser.get_tab(tab_id)
        if forward == "down":
            if pixel is None:
                target_tab.scroll.to_half()
            else:
                target_tab.scroll.down(pixel)
        elif forward == "up":
            if pixel is None:
                target_tab.scroll.to_top()
            else:
                target_tab.scroll.up(pixel)
        elif forward == "left":
            if pixel is None:
                target_tab.scroll.to_leftmost()
            else:
                target_tab.scroll.left(pixel)
        elif forward == "right":
            if pixel is None:
                target_tab.scroll.to_rightmost()
            else:
                target_tab.scroll.right(pixel)
        else:
            if pixel is None:
                target_tab.scroll.to_half()
            else:
                target_tab.scroll.down()
        message = f"已完成对tab页:【{tab_id}】forward={forward} 的滑动"
        return dp_mcp_message_pack(
            message=message,
            browser_port=browser_port,
            tab_id=tab_id,
        )


def register_mouse_hover(mcp: FastMCP, browser_manager):
    @mcp.tool(name="mouse_hover", description="将鼠标悬停在元素上【这个功能使用了Drissionpage的action行为链功能】")
    async def mouse_hover(browser_port: int, tab_id: str, css_selector: str, target_element_index: int = 0) -> dict[
        str, Any]:
        _browser = browser_manager.get_browser(browser_port)
        target_tab = _browser.get_tab(tab_id)
        css_selector = css_selector
        if "css:" not in css_selector:
            css_selector = "css:" + css_selector
        target_eles = target_tab.eles(css_selector)
        target_element = target_eles[target_element_index]
        try:
            target_tab.actions.move_to(target_element)
            target_element.hover()
            hover_success = True
        except Exception as e:
            hover_success = False
        if target_element_index > 0:
            message = f"tab页:【{tab_id}】hover【{css_selector}】【index={target_element_index}】的元素 {'成功' if hover_success else '失败'} 了"
        else:
            message = f"tab页:【{tab_id}】hover【{css_selector}】 {'成功' if hover_success else '失败'} 了"
        # else:
        #     message = f"tab页:【{tab_id}】传入的css_selector找到了{len(target_eles)}个元素，请确保传入的css_selector可以找到唯一的一个元素"
        return dp_mcp_message_pack(
            message=message,
            browser_port=browser_port,
            tab_id=tab_id,
            css_selector=css_selector,
            hoversuccess=hover_success,
            extra_message="hover成功，页面可能有更新，请重新获取页面html，并重新分析页面Selector" if hover_success else ""
        )
