export const delegateTriggerEvent = <T extends HTMLElement>(eventName: string, target: T, value?: unknown) => {
  if (typeof window === 'undefined') {
    return;
  }

  const TAG_NAME_ELEMENT_CONSTRUCTOR = {
    'INPUT': window.HTMLInputElement,
    'SELECT': window.HTMLSelectElement,
    'TEXTAREA': window.HTMLTextAreaElement,
  } as const;

  const { [target.tagName as keyof typeof TAG_NAME_ELEMENT_CONSTRUCTOR]: elementCtor } = TAG_NAME_ELEMENT_CONSTRUCTOR;

  if (!elementCtor) {
    return;
  }

  if (eventName === 'change') {
    const nativeInputValueSetter = Object.getOwnPropertyDescriptor(elementCtor.prototype, 'value')?.set;
    if (nativeInputValueSetter) {
      if (
        (target.tagName === 'INPUT' && (target as unknown as HTMLInputElement).type !== 'file')
        || target.tagName !== 'INPUT'
      ) {
        nativeInputValueSetter.call(target, value);
      }
      const simulatedEvent = new Event(eventName, {bubbles: true});
      target.dispatchEvent(simulatedEvent);
    }
    return;
  }

  if (eventName === 'blur') {
    target.focus({
      preventScroll: true,
    });
    setTimeout(() => {
      target.blur();
    });
  }
  const simulatedEvent = new Event(eventName, {bubbles: true});
  target.dispatchEvent(simulatedEvent);
}
