/*
 * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
 *
 * SPDX-License-Identifier: AGPL-3.0-only
 */

/**
 * Converts an inline style string into an object of React style properties
 *
 * @param {String} inlineStyle='' The inline style to convert
 * @returns {Object} The converted style
 */
export function convertInlineStyleToMap(
  inlineStyle = ''
): Record<string, string> {
  if (inlineStyle === '') {
    return {}
  }

  const statements: string[] = []
  let i = -1
  let offset = 0
  do {
    i++
    let curr = inlineStyle[i]
    let prev = inlineStyle[i - 1]

    if ((curr === "'" || curr === '"') && prev !== '\\') {
      const quote = curr
      do {
        i++
        curr = inlineStyle[i]
        prev = inlineStyle[i - 1]
      } while (!(curr === quote && prev !== '\\') && i < inlineStyle.length)
      continue
    }

    if (curr === ';' && prev !== '\\') {
      statements.push(inlineStyle.slice(offset, i))
      offset = i + 1
      continue
    }
  } while (i < inlineStyle.length)
  statements.push(inlineStyle.slice(offset, inlineStyle.length))

  return statements.reduce<Record<string, string>>(
    (styleObject, stylePropertyValue) => {
      // extract the style property name and value
      const [property, value] = stylePropertyValue
        .split(/^([^:]+):/)
        .filter((val, i) => i > 0)
        .map((item) => item.trim())

      // if there is no value (i.e. no : in the style) then ignore it
      if (value === undefined) {
        return styleObject
      }

      // convert the property name into the correct React format
      // remove all hyphens and convert the letter immediately after each hyphen to upper case
      // additionally don't uppercase any -ms- prefix
      // e.g. -ms-style-property = msStyleProperty
      //      -webkit-style-property = WebkitStyleProperty
      const replacedProperty = property
        .toLowerCase()
        .replace(/^-ms-/, 'ms-')
        .replace(/-(.)/g, (_, character: string) => character.toUpperCase())

      // add the new style property and value to the style object
      styleObject[replacedProperty] = value

      return styleObject
    },
    {}
  )
}