"""
    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
from DrissionPage.common import Keys


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
        try:
            has_rect = target_element.states.has_rect
            is_covered = target_element.states.is_covered
            click_success = not is_covered
            if not is_covered:
                target_tab.actions.move_to(target_element)
                target_tab.actions.click()
        except NoRectError:
            has_rect = False
            is_covered = True
            click_success = False
        except Exception as e:
            click_success = False
            has_rect = target_element.states.has_rect
            if has_rect:
                is_covered = target_element.states.is_covered
            else:
                is_covered = True
        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 not 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_hover_action(mcp: FastMCP, browser_manager):
    @mcp.tool(name="hover_action", description="将鼠标悬停在元素上【这个功能使用了Drissionpage的action行为链功能】")
    async def hover_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]
        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,
            target_element_index=target_element_index,
            hoversuccess=hover_success,
            extra_message="hover成功，页面可能有更新，请重新获取页面html，并重新分析页面Selector" if hover_success else ""
        )


def register_select_action(mcp: FastMCP, browser_manager):
    @mcp.tool(name="select_action", description="使用传入的css_selector和target_element_index找到想要选取的select元素，"
                                                "通过传入的target_option选择option。"
                                                "target_option提供两种选择模式，在值为int类型时使用的是option的下标【默认为1，选择第一个】。"
                                                "在值为str类型时使用的是option元素的text")
    async def select_action(browser_port: int, tab_id: str, css_selector: str, target_element_index: int = 0,
                            target_option: int | str = 1) -> 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]
        if isinstance(target_option, int):
            target_element.select.by_index(target_option)
            message = f"tab页:【tab_id={tab_id}】【css_selector={css_selector}，target_element_index={target_element_index}】选择成功，当前的option为：【target_option={target_option}】"
        elif isinstance(target_option, str):
            target_element.select.by_text(target_option)
            message = f"tab页:【tab_id={tab_id}】【css_selector={css_selector}，target_element_index={target_element_index}】选择成功，当前的option为：【target_option={target_option}】"
        else:
            message = "请传入正确的target_option，target_option必须为str【对应option元素的text】或是int类型【对应option元素的index，从1开始计数】"
        return dp_mcp_message_pack(
            message=message,
            browser_port=browser_port,
            tab_id=tab_id,
            css_selector=css_selector,
            target_option=target_option,
            target_element_index=target_element_index,
            extra_message="select选择成功，页面可能有更新，请重新获取页面html，并重新分析页面Selector" if "成功" in message else ""
        )


def register_input_action(mcp: FastMCP, browser_manager):
    @mcp.tool(name="input_action", description="")
    async def input_action(browser_port: int, tab_id: str, css_selector: str, target_element_index: int = 0,
                           input_content: Any = None, type_enter: bool = False) -> 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]
        enter_message = ""
        target_element.focus()
        if input_content:
            target_element.input(input_content, clear=True)
        if type_enter:
            target_element.input(Keys.ENTER)
            enter_message = f"，并成功在输入后，键入回车键"
        message = f"tab页:【tab_id={tab_id}】【css_selector={css_selector}，target_element_index={target_element_index}】成功输入input_content={input_content}" + enter_message
        return dp_mcp_message_pack(
            message=message,
            browser_port=browser_port,
            tab_id=tab_id,
            css_selector=css_selector,
            target_element_index=target_element_index,
            input_content=input_content,
        )
