"""MultiSelect and MultiEdit tools — batch element interaction."""

from mcp.types import ToolAnnotations
from windows_mcp.analytics import with_analytics
from fastmcp import Context


def register(mcp, *, get_desktop, get_analytics):
    @mcp.tool(
        name="MultiSelect",
        description="Selects multiple items such as files, folders, or checkboxes if press_ctrl=True, or performs multiple clicks if False. Pass locs (list of coordinates) or labels (list of UI element labels/ids).",
        annotations=ToolAnnotations(
            title="MultiSelect",
            readOnlyHint=False,
            destructiveHint=True,
            idempotentHint=False,
            openWorldHint=False,
        ),
    )
    @with_analytics(get_analytics(), "Multi-Select-Tool")
    def multi_select_tool(
        locs: list[list[int]] | None = None,
        labels: list[int] | None = None,
        press_ctrl: bool | str = True,
        ctx: Context = None,
    ) -> str:
        desktop = get_desktop()
        if locs is None and labels is None:
            raise ValueError("Either locs or labels must be provided.")
        locs = locs or []
        if labels is not None:
            if desktop.desktop_state is None:
                raise ValueError("Desktop state is empty. Please call Snapshot first.")
            for label in labels:
                try:
                    locs.append(list(desktop.get_coordinates_from_label(label)))
                except Exception as e:
                    raise ValueError(f"Failed to find element with label {label}: {e}")

        press_ctrl = press_ctrl is True or (
            isinstance(press_ctrl, str) and press_ctrl.lower() == "true"
        )
        desktop.multi_select(press_ctrl, locs)
        elements_str = "\n".join([f"({loc[0]},{loc[1]})" for loc in locs])
        return f"Multi-selected elements at:\n{elements_str}"

    @mcp.tool(
        name="MultiEdit",
        description="Enters text into multiple input fields at specified coordinates locs=[[x,y,text], ...] or using labels=[[label,text], ...]. Provide either locs or labels.",
        annotations=ToolAnnotations(
            title="MultiEdit",
            readOnlyHint=False,
            destructiveHint=True,
            idempotentHint=False,
            openWorldHint=False,
        ),
    )
    @with_analytics(get_analytics(), "Multi-Edit-Tool")
    def multi_edit_tool(
        locs: list[list] | None = None,
        labels: list[list] | None = None,
        ctx: Context = None,
    ) -> str:
        desktop = get_desktop()
        if locs is None and labels is None:
            raise ValueError("Either locs or labels must be provided.")
        locs = locs or []
        if labels is not None:
            if desktop.desktop_state is None:
                raise ValueError("Desktop state is empty. Please call Snapshot first.")
            for item in labels:
                if len(item) != 2:
                    raise ValueError(f"Each label item must be [label, text]. Invalid: {item}")
                try:
                    label, text = int(item[0]), item[1]
                    loc = list(desktop.get_coordinates_from_label(label))
                    locs.append([loc[0], loc[1], text])
                except Exception as e:
                    raise ValueError(f"Failed to process label item {item}: {e}")

        desktop.multi_edit(locs)
        elements_str = ", ".join([f"({e[0]},{e[1]}) with text '{e[2]}'" for e in locs])
        return f"Multi-edited elements at: {elements_str}"
