import { Property } from 'csstype'

import colors from '../theme/foundations/colors'

/** Concatenates individual className arguments and returns a single string. */
export function cs(...classNames: any[]) {
  return classNames.filter(Boolean).join(' ')
}

/** Parses HSL color code. */
export function parseHSL(color: string) {
  const regexp = /hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g
  const res = regexp?.exec?.(color)?.slice?.(1)
  return { h: Number(res?.[0]) || 0, s: Number(res?.[1]) || 0, l: Number(res?.[2]) || 0 }
}

/** Converts hex color value to rgb with optional alpha property. */
export function hexToRGBA(hex: string, alpha?: number) {
  let hexStr = hex

  if (hexStr.charAt(0) === '#') hexStr = hexStr.slice(1)

  if (hexStr.length < 4)
    hexStr = hexStr
      .split('')
      .map(char => char + char)
      .join('')

  const r = parseInt(hexStr.slice(0, 2), 16)
  const g = parseInt(hexStr.slice(2, 4), 16)
  const b = parseInt(hexStr.slice(4, 6), 16)

  return alpha !== undefined ? `rgba(${r}, ${g}, ${b}, ${alpha})` : `rgb(${r}, ${g}, ${b})`
}

export function vuiColorToRGBA(color: string, alpha?: number) {
  if (!color.includes('.')) return 'transparent'

  const [colorName, shade] = color.split('.')

  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
  const x = parseHSL(colors[colorName][shade])
  return HSLToRGBA(x.h, x.s, x.l, alpha || shade === 'main' ? 1 : parseInt(shade))
}

/** Converts hsl color value to rgb with optional alpha property. */
export function HSLToRGBA(h: number, s: number, l: number, alpha?: number) {
  s /= 100
  l /= 100

  const c = (1 - Math.abs(2 * l - 1)) * s,
    x = c * (1 - Math.abs(((h / 60) % 2) - 1)),
    m = l - c / 2

  let r = 0,
    g = 0,
    b = 0

  if (0 <= h && h < 60) {
    r = c
    g = x
    b = 0
  } else if (60 <= h && h < 120) {
    r = x
    g = c
    b = 0
  } else if (120 <= h && h < 180) {
    r = 0
    g = c
    b = x
  } else if (180 <= h && h < 240) {
    r = 0
    g = x
    b = c
  } else if (240 <= h && h < 300) {
    r = x
    g = 0
    b = c
  } else if (300 <= h && h < 360) {
    r = c
    g = 0
    b = x
  }
  r = Math.round((r + m) * 255)
  g = Math.round((g + m) * 255)
  b = Math.round((b + m) * 255)

  return alpha !== undefined ? `rgba(${r}, ${g}, ${b}, ${alpha})` : `rgb(${r}, ${g}, ${b})`
}

/** Styling to add ellipsis for long texts. */
export const ellipsisOverflow = {
  overflow: 'hidden',
  textOverflow: 'ellipsis',
  whiteSpace: 'nowrap' as Property.WhiteSpace,
}
