/**
 * Helper JS file for template
 * @package fga.marketing-materials
 */
/// <reference path="../../types/app.d.ts" />
const select = (selectorOrElement, selector) => {
  if (typeof selectorOrElement === "string") {
    return document.querySelector(selectorOrElement);
  } else {
    return selectorOrElement.querySelector(selector);
  }
}

const selectAll = (selectorOrElement, selector) => {
  if (typeof selectorOrElement === "string") {
    return document.querySelectorAll(selectorOrElement);
  } else {
    return selectorOrElement.querySelectorAll(selector);
  }
}

const create = (var1, var2, var3) => {
  const element = document.createElement(var1);

  const handleAttr = (attr) => {
    Object.entries(attr).forEach(([key, value]) => {
      if (key === "classList") {
        if (!value) return;
        const classes = value.split(" ");
        classes.forEach((className) => element.classList.add(className));
      } else if (key === "style") {
        Object.entries(value).forEach(([k, v]) => {
          if (k.startsWith("--")) {
            element.style.setProperty(k, v);
          } else {
            element.style[k] = v;
          }
        });
      } else {
        element.setAttribute(key, value);
      }
    });
  };

  const handleChildren = (children) => {
    children.forEach((value) => {
      if (value instanceof HTMLElement) {
        element.appendChild(value);
      } else if (typeof value === "string") {
        element.appendChild(create("p", value));
      }
    });
  };

  if (typeof var2 === "string") {
    element.innerHTML = interpolate(var2);
  } else if (Array.isArray(var2)) {
    handleChildren(var2);
  } else if (typeof var2 === "object") {
    handleAttr(var2);
  }

  if (typeof var3 === "string") {
    element.innerHTML = interpolate(var3);
  } else if (Array.isArray(var3)) {
    handleChildren(var3);
  }

  return element;
};

const interpolate = (text, context = {}) => {
  const regex = /{{(.*?)}}/g;

  return text.replace(regex, (match, code) => {
    try {
      const func = new Function(
        ...Object.keys(context),
        `return ${code.trim()};`,
      );
      return func(...Object.values(context));
    } catch (error) {
      console.error(`Error evaluating code: ${code}`, error);
      return match;
    }
  });
};

const toggleCls = (element, ...classes) => {
  classes.forEach((cls) => element.classList.toggle(cls));
};

const addCls = (element, ...classes) => {
  classes.forEach((cls) => element.classList.add(cls));
};

const removeCls = (element, ...classes) => {
  classes.forEach((cls) => element.classList.remove(cls));
};

const recursiveChildren = (children) => {
  if (!children) return null;

  return children.filter(Boolean).map((child) => {
    const { attributes = {}, children: childChildren, type } = child;
    const text = attributes.innerHTML ?? "";
    delete attributes.innerHTML;

    const element = create(
      type,
      attributes,
      text || (recursiveChildren(childChildren) ?? []),
    );

    return element;
  });
};