import { onMessage } from 'webext-bridge/content-script';
import { EVENT_TAB_ON_CHANGE } from '@/bridge/config/event';
import { bridgeGetScriptUrl } from '@/bridge/content/background';

export const setNativeValue = (elementSet, valueSet) => {
  const lastValue = elementSet.value;
  elementSet.value = valueSet;
  const event = new Event('input', {
    target: elementSet,
    bubbles: !0,
  });
  event.simulated = !0;
  const tracker = elementSet._valueTracker;
  if (tracker) {
    tracker.setValue(lastValue);
  }
  elementSet.dispatchEvent(event);
};

export const setInputNative = (elementSet, valueSet) => {
  const lastValue = elementSet.value;
  elementSet.value = valueSet;
  const eventInput = new Event('input', {
    target: elementSet,
    bubbles: true,
  });

  const eventChange = new Event('change', {
    target: elementSet,
    bubbles: true,
  });

  eventInput.simulated = true;
  const tracker = elementSet._valueTracker;
  if (tracker) {
    tracker.setValue(lastValue);
  }

  elementSet.dispatchEvent(eventInput);
  elementSet.dispatchEvent(eventChange);
};

export const appendStyle = async (styleCss) => {
  const elementStyle = document.createElement('style');

  elementStyle.innerHTML = styleCss;

  document.head.appendChild(elementStyle);
};

export const onChangeTab = (callback) => {
  onMessage(EVENT_TAB_ON_CHANGE, ({ data: tabChange }) => {
    callback(tabChange);
  });
};

export const onLocationChange = (callback) => {
  window.addEventListener('wxt:locationchange', ({ detail }) => {
    callback(detail);
  });
};

/**
 *
 * @param {Element} referenceNode
 * @param {Element} newNode
 */
export const appendNextNode = (referenceNode, newNode) => {
  referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
};

export const loadScriptUrl = async (fileName) => {
  const { scriptUrl } = await bridgeGetScriptUrl(fileName);

  const scriptEmbed = document.createElement('script');
  scriptEmbed.src = scriptUrl;
  (document.head || document.documentElement).appendChild(scriptEmbed);

  return scriptUrl;
};
