// Copyright 2023 The Lynx Authors. All rights reserved.
// Licensed under the Apache License Version 2.0 that can be found in the
// LICENSE file in the root directory of this source tree.
import { HTML_TAG_TO_LYNX_TAG_MAP, lynxElementTemplateMarkerAttribute, lynxPartIdAttribute, uniqueIdSymbol, ErrorCode, } from '../../../constants.js';
export const __AppendElement = /*#__PURE__*/ (parent, child) => parent.appendChild(child);
export const __ElementIsEqual = /*#__PURE__*/ (left, right) => left === right;
export const __FirstElement = /*#__PURE__*/ (element) => element.firstElementChild;
export const __GetChildren = /*#__PURE__*/ (element) => element.children ? [...element.children] : null;
export const __GetParent = /*#__PURE__*/ (element) => element.parentElement;
export const __InsertElementBefore = /*#__PURE__*/ (parent, child, ref) => parent.insertBefore(child, ref);
export const __LastElement = /*#__PURE__*/ (element) => element.lastElementChild;
export const __NextElement = /*#__PURE__*/ (element) => element.nextElementSibling;
export const __RemoveElement = /*#__PURE__*/ (parent, child) => parent.removeChild(child);
export const __ReplaceElement = /*#__PURE__*/ (newElement, oldElement) => oldElement.replaceWith(newElement);
export const __ReplaceElements = /*#__PURE__*/ (parent, newChildren, oldChildren) => {
    newChildren = Array.isArray(newChildren) ? newChildren : [newChildren];
    if (!oldChildren || (Array.isArray(oldChildren) && oldChildren?.length === 0)) {
        parent.append(...newChildren);
    }
    else {
        oldChildren = Array.isArray(oldChildren) ? oldChildren : [oldChildren];
        for (let ii = 1; ii < oldChildren.length; ii++) {
            __RemoveElement(parent, oldChildren[ii]);
        }
        const firstOldChildren = oldChildren[0];
        firstOldChildren.replaceWith(...newChildren);
    }
};
export const __GetAttributes = /*#__PURE__*/ (element) => {
    return Object.fromEntries(element.getAttributeNames().map((attributeName) => [attributeName, element.getAttribute(attributeName)])
        .filter(([, value]) => value));
};
export const __GetAttributeByName = /*#__PURE__*/ (element, name) => element.getAttribute(name);
export const __GetID = /*#__PURE__*/ (element) => element.getAttribute('id');
export const __SetID = /*#__PURE__*/ (element, id) => id ? element.setAttribute('id', id) : element.removeAttribute('id');
export const __GetTag = /*#__PURE__*/ (element) => {
    const tagName = element.tagName.toLowerCase();
    return HTML_TAG_TO_LYNX_TAG_MAP[tagName] ?? tagName;
};
export const __GetClasses = /*#__PURE__*/ (element) => [...element.classList];
export const __SwapElement = /*#__PURE__*/ (childA, childB) => {
    const temp = document.createElement('div');
    childA.replaceWith(temp);
    childB.replaceWith(childA);
    temp.replaceWith(childB);
};
export const __SetClasses = /*#__PURE__*/ (element, classname) => {
    classname
        ? element.setAttribute('class', classname)
        : element.removeAttribute('class');
};
export const __AddClass = /*#__PURE__*/ (element, className) => {
    element.classList.add(className);
};
export const __GetTemplateParts = (templateElement) => {
    const isTemplate = templateElement.getAttribute(lynxElementTemplateMarkerAttribute)
        !== null;
    if (!isTemplate) {
        return {};
    }
    const templateUniqueId = __GetElementUniqueID(templateElement);
    const parts = {};
    const partElements = templateElement.querySelectorAll(`[${lynxPartIdAttribute}]:not([${lynxElementTemplateMarkerAttribute}="${templateUniqueId}"] [${lynxElementTemplateMarkerAttribute}] [${lynxPartIdAttribute}])`);
    for (const partElement of partElements) {
        const partId = partElement.getAttribute(lynxPartIdAttribute);
        if (partId) {
            parts[partId] = partElement;
        }
    }
    return parts;
};
export const __MarkTemplateElement = (element) => {
    const templateUniqueId = __GetElementUniqueID(element);
    element.setAttribute(lynxElementTemplateMarkerAttribute, templateUniqueId.toString());
};
export const __MarkPartElement = (element, partId) => {
    element.setAttribute(lynxPartIdAttribute, partId);
};
export const __GetElementUniqueID = /*#__PURE__*/ (element) => (element && element[uniqueIdSymbol]) ?? -1;
export const __UpdateListCallbacks = /*#__PURE__*/ (element, componentAtIndex, enqueueComponent) => {
    const decoratedElement = element;
    decoratedElement.componentAtIndex = componentAtIndex;
    decoratedElement.enqueueComponent = enqueueComponent;
};
const methodAlias = {
    'boundingClientRect': (element) => {
        const rect = element.getBoundingClientRect();
        return {
            id: element.id,
            width: rect.width,
            height: rect.height,
            left: rect.left,
            right: rect.right,
            top: rect.top,
            bottom: rect.bottom,
        };
    },
};
export const __InvokeUIMethod = /*#__PURE__*/ (element, method, params, callback) => {
    let code = ErrorCode.UNKNOWN;
    let data = undefined;
    try {
        const aliasMethod = methodAlias[method];
        const hasDomMethod = typeof element[method] === 'function';
        if (!aliasMethod && !hasDomMethod) {
            code = ErrorCode.METHOD_NOT_FOUND;
        }
        else {
            if (aliasMethod) {
                data = aliasMethod(element, params);
            }
            else {
                data = element[method](params);
            }
            code = ErrorCode.SUCCESS;
        }
    }
    catch (e) {
        console.error(`[lynx-web] invokeUIMethod: apply method failed with`, e, element);
        code = ErrorCode.PARAM_INVALID;
    }
    callback({ code, data });
};
export const __QuerySelector = /*#__PURE__*/ (element, selector, _options) => {
    return element.querySelector(selector);
};
export const __QuerySelectorAll = /*#__PURE__*/ (element, selector, _options) => {
    return Array.from(element.querySelectorAll(selector));
};
//# sourceMappingURL=pureElementPAPIs.js.map