module.exports = function(lab1, lab2) {
  const rgb2labArray1 = lab1
  const rgb2labArray2 = lab2

  const l1 = rgb2labArray1[0]
  const a1 = rgb2labArray1[1]
  const b1 = rgb2labArray1[2]

  const l2 = rgb2labArray2[0]
  const a2 = rgb2labArray2[1]
  const b2 = rgb2labArray2[2]

  const avg_lp = (l1 + l2) / 2
  const c1 = Math.sqrt(Math.pow(a1, 2) + Math.pow(b1, 2))
  const c2 = Math.sqrt(Math.pow(a2, 2) + Math.pow(b2, 2))
  const avg_c = (c1 + c2) / 2
  const g = (1 - Math.sqrt(Math.pow(avg_c, 7) / (Math.pow(avg_c, 7) + Math.pow(25, 7)))) / 2

  const a1p = a1 * (1 + g)
  const a2p = a2 * (1 + g)

  const c1p = Math.sqrt(Math.pow(a1p, 2) + Math.pow(b1, 2))
  const c2p = Math.sqrt(Math.pow(a2p, 2) + Math.pow(b2, 2))

  const avg_cp = (c1p + c2p) / 2

  let h1p = rad2deg(Math.atan2(b1, a1p))
  if (h1p < 0) {
    h1p = h1p + 360
  }

  let h2p = rad2deg(Math.atan2(b2, a2p))
  if (h2p < 0) {
    h2p = h2p + 360
  }

  const avg_hp = Math.abs(h1p - h2p) > 180 ? (h1p + h2p + 360) / 2 : (h1p + h1p) / 2

  const t = 1 - 0.17 * Math.cos(deg2rad(avg_hp - 30)) + 0.24 * Math.cos(deg2rad(2 * avg_hp)) + 0.32 * Math.cos(deg2rad(3 * avg_hp + 6)) - 0.2 * Math.cos(deg2rad(4 * avg_hp - 63))

  let delta_hp = h2p - h1p
  if (Math.abs(delta_hp) > 180) {
    if (h2p <= h1p) {
      delta_hp += 360
    }
    else {
      delta_hp -= 360
    }
  }

  const delta_lp = l2 - l1
  const delta_cp = c2p - c1p

  delta_hp = 2 * Math.sqrt(c1p * c2p) * Math.sin(deg2rad(delta_hp) / 2)

  const s_l = 1 + ((0.015 * Math.pow(avg_lp - 50, 2)) / Math.sqrt(20 + Math.pow(avg_lp - 50, 2)))
  const s_c = 1 + 0.045 * avg_cp
  const s_h = 1 + 0.015 * avg_cp * t

  const delta_ro = 30 * Math.exp(-(Math.pow((avg_hp - 275) / 25, 2)))
  const r_c = 2 * Math.sqrt(Math.pow(avg_cp, 7) / (Math.pow(avg_cp, 7) + Math.pow(25, 7)))
  const r_t = -r_c * Math.sin(2 * deg2rad(delta_ro))

  const kl = 1; const kc = 1; const kh = 1

  const delta_e = Math.sqrt(Math.pow(delta_lp / (kl * s_l), 2) + Math.pow(delta_cp / (kc * s_c), 2) + Math.pow(delta_hp / (kh * s_h), 2) + r_t * (delta_cp / (kc * s_c)) * (delta_hp / (kh * s_h)))

  return delta_e

  function rad2deg(rad) {
    return 360 * rad / (2 * Math.PI)
  }
  function deg2rad(deg) {
    return (2 * Math.PI * deg) / 360
  }
}
