"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.findElementByLocation = findElementByLocation;
const domUtils_1 = require("../sharedUtils/domUtils");
const dom_util_1 = require("@mablhq-internal/mablscript-find/dom-util");
const mablscriptFind_1 = require("@mablhq/test-model/mablscriptFind");
const domTools_1 = require("./domTools");
const messages_1 = require("../sharedUtils/messages");
async function findElementByLocation({ boundingBox, targetPoint, toolCall, }, highlight = true) {
    if (!boundingBox && !targetPoint) {
        return;
    }
    const highlightBoxPromise = boundingBox && highlight
        ? createHighlightBoxForLocation(boundingBox)
        : Promise.resolve();
    const scaledTarget = targetPoint ?? (0, mablscriptFind_1.getBoundingBoxCenter)(boundingBox);
    const highlightPointPromise = targetPoint && highlight
        ? createHighlightPoint(targetPoint)
        : Promise.resolve();
    const elementsAtPoint = (0, domUtils_1.getElementsAtPosition)(scaledTarget.x, scaledTarget.y);
    const elements = filterElementsAtPoint(elementsAtPoint, toolCall);
    const target = elements[0];
    if (!target) {
        throw new Error('No element found at the specified location');
    }
    const xPath = (0, dom_util_1.createXPathFromElement)(target);
    const eventMessage = await (0, domTools_1.createEventMessageWithShadowParents)(target, messages_1.FIND_BY_LOCATION, messages_1.FIND_BY_LOCATION, xPath, Date.now());
    eventMessage.availableAttrProps = (0, dom_util_1.getAttributePropertyMap)(target);
    eventMessage.selectOptions = (0, domTools_1.extractSelectOptions)(target);
    await Promise.all([highlightBoxPromise, highlightPointPromise]);
    return { payload: eventMessage, target };
}
const HIGHLIGHT_BOX_Z_INDEX = 9999999;
async function createHighlightBoxForLocation(location) {
    const highlightBox = document.createElement('div');
    const className = 'mabl-found-element-highlight-box';
    highlightBox.className = className;
    highlightBox.style.position = 'absolute';
    highlightBox.style.zIndex = HIGHLIGHT_BOX_Z_INDEX.toString();
    highlightBox.style.border = '2px solid rgba(255, 0, 255, 0.8)';
    highlightBox.style.backgroundColor = 'rgba(255, 0, 255, 0.2)';
    highlightBox.style.pointerEvents = 'none';
    highlightBox.style.left = `${location.x + window.scrollX}px`;
    highlightBox.style.top = `${location.y + window.scrollY}px`;
    highlightBox.style.width = `${location.width}px`;
    highlightBox.style.height = `${location.height}px`;
    const animation = `@keyframes fadeInOut {
    0% { opacity: 0; }
    50% { opacity: 1; }
    100% { opacity: 0; }
  }`;
    highlightBox.style.animation = 'fadeInOut 1.0s ease-in-out forwards';
    const styleSheet = document.createElement('style');
    styleSheet.textContent = animation;
    document.head.appendChild(styleSheet);
    document.body.appendChild(highlightBox);
    await new Promise((resolve) => {
        globalThis.setTimeout(() => {
            document.body.removeChild(highlightBox);
            document.head.removeChild(styleSheet);
            resolve();
        }, 1_000);
    });
}
async function createHighlightPoint(point) {
    const highlightPoint = document.createElement('div');
    const className = 'mabl-found-element-highlight-point';
    highlightPoint.className = className;
    highlightPoint.style.position = 'absolute';
    highlightPoint.style.zIndex = (HIGHLIGHT_BOX_Z_INDEX + 1).toString();
    highlightPoint.style.width = '16px';
    highlightPoint.style.height = '16px';
    highlightPoint.style.borderRadius = '50%';
    highlightPoint.style.border = '2px solid #6b68cf';
    highlightPoint.style.backgroundColor = 'white';
    highlightPoint.style.pointerEvents = 'none';
    highlightPoint.style.left = `${point.x + window.scrollX}px`;
    highlightPoint.style.top = `${point.y + window.scrollY}px`;
    highlightPoint.style.transform = 'translate(-50%, -50%)';
    highlightPoint.style.boxSizing = 'border-box';
    const animation = `@keyframes pointFadeInOut {
    0% { opacity: 0; }
    50% { opacity: 1; }
    100% { opacity: 0; }
  }`;
    highlightPoint.style.animation = 'pointFadeInOut 1.0s ease-in-out forwards';
    const styleSheet = document.createElement('style');
    styleSheet.textContent = animation;
    document.head.appendChild(styleSheet);
    document.body.appendChild(highlightPoint);
    await new Promise((resolve) => {
        globalThis.setTimeout(() => {
            document.body.removeChild(highlightPoint);
            document.head.removeChild(styleSheet);
            resolve();
        }, 1_000);
    });
}
function filterElementsAtPoint(elements, toolCall) {
    const toolName = toolCall?.toolName;
    if (toolName === 'execute_enter_text') {
        const textInputElements = elements.filter((el) => {
            const tagName = el.tagName.toLowerCase();
            return (tagName === 'input' ||
                tagName === 'textarea' ||
                (tagName === 'select' && el.nodeName !== 'optgroup'));
        });
        return textInputElements.length > 0 ? textInputElements : elements;
    }
    else if (toolName === 'execute_assert_element') {
        const toolParams = toolCall?.toolParams;
        const elementsContainingExpectedText = elements.filter((el) => {
            const elementText = (0, dom_util_1.normalizeText)(el.innerText.toLowerCase());
            const expectedText = (0, dom_util_1.normalizeText)(toolParams.textToAssert.toLowerCase());
            return elementText.includes(expectedText);
        });
        return elementsContainingExpectedText.length > 0
            ? elementsContainingExpectedText
            : elements;
    }
    return elements;
}
