export const camelCaseToDashed = (camelCase: string) => {
  return camelCase.replace(/[A-Z]/g, (m) => '-' + m.toLowerCase());
};

export const getBoundingClientRect = (node: SVGElement) => {
  if (node) {
    const isElement = node.nodeType === 1; /* Node.ELEMENT_NODE */
    if (isElement && typeof node.getBoundingClientRect === 'function') {
      return node.getBoundingClientRect();
    }
  }
  throw new Error('Can not get boundingClientRect of ' + node || 'undefined');
};

const measureLayout = (
  node: SVGElement,
  callback: (
    x: number,
    y: number,
    width: number,
    height: number,
    left: number,
    top: number
  ) => void
) => {
  const relativeNode = node?.parentNode;
  if (relativeNode) {
    setTimeout(() => {
      // @ts-expect-error TODO: handle it better
      const relativeRect = getBoundingClientRect(relativeNode);
      const { height, left, top, width } = getBoundingClientRect(node);
      const x = left - relativeRect.left;
      const y = top - relativeRect.top;
      callback(x, y, width, height, left, top);
    }, 0);
  }
};

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function remeasure(this: any) {
  const tag = this.state.touchable.responderID;
  if (tag === null) {
    return;
  }
  measureLayout(tag, this._handleQueryLayout);
}

/* Taken from here: https://gist.github.com/jennyknuth/222825e315d45a738ed9d6e04c7a88d0 */
export function encodeSvg(svgString: string) {
  return svgString
    .replace(
      '<svg',
      ~svgString.indexOf('xmlns')
        ? '<svg'
        : '<svg xmlns="http://www.w3.org/2000/svg"'
    )
    .replace(/"/g, "'")
    .replace(/%/g, '%25')
    .replace(/#/g, '%23')
    .replace(/{/g, '%7B')
    .replace(/}/g, '%7D')
    .replace(/</g, '%3C')
    .replace(/>/g, '%3E')
    .replace(/\s+/g, ' ');
}

const KEEP_CAMEL_CASE = new Set([
  'stdDeviation',
  'edgeMode',
  'kernelMatrix',
  'kernelUnitLength',
  'preserveAlpha',
  'baseFrequency',
  'targetX',
  'targetY',
  'numOctaves',
  'stitchTiles',
  'filterUnits',
  'primitiveUnits',
  'pathLength',
  'gradientUnits',
  'gradientTransform',
  'spreadMethod',
  'markerHeight',
  'markerUnits',
  'markerWidth',
  'viewBox',
  'refX',
  'refY',
  'maskContentUnits',
  'maskUnits',
  'patternContentUnits',
  'patternTransform',
  'patternUnits',
  'textLength',
  'lengthAdjust',
  'startOffset',
  'clipPathUnits',
]);

export const getAttributeName = (attr: string) => {
  return KEEP_CAMEL_CASE.has(attr) ? attr : camelCaseToDashed(attr);
};
