import { theme } from "@chakra-ui/react"
import { tinycolor } from "@ctrl/tinycolor"

/**
 * The color for the edge with given back pressure value.
 *
 * @param value The back pressure rate, between 0 and 100.
 */
export function backPressureColor(value: number) {
  const colorRange = [
    theme.colors.green["100"],
    theme.colors.green["300"],
    theme.colors.yellow["400"],
    theme.colors.orange["500"],
    theme.colors.red["700"],
  ].map((c) => tinycolor(c))

  value = Math.max(value, 0)
  value = Math.min(value, 1)

  const step = colorRange.length - 1
  const pos = value * step
  const floor = Math.floor(pos)
  const ceil = Math.ceil(pos)

  const color = tinycolor(colorRange[floor])
    .mix(tinycolor(colorRange[ceil]), (pos - floor) * 100)
    .toHexString()

  return color
}

/**
 * The width for the edge with given back pressure value.
 *
 * @param value The back pressure rate, between 0 and 100.
 */
export function backPressureWidth(value: number, scale: number) {
  value = Math.max(value, 0)
  value = Math.min(value, 1)

  return scale * value + 2
}

export function epochToUnixMillis(epoch: number) {
  // UNIX_RISINGWAVE_DATE_SEC
  return 1617235200000 + epoch / 65536
}

export function latencyToColor(latency_ms: number, baseColor: string) {
  const LOWER = 10000 // 10s
  const UPPER = 300000 // 5min

  const colorRange = [
    baseColor,
    theme.colors.yellow["200"],
    theme.colors.orange["300"],
    theme.colors.red["400"],
  ].map((c) => tinycolor(c))

  if (latency_ms <= LOWER) {
    return baseColor
  }

  if (latency_ms >= UPPER) {
    return theme.colors.red["400"]
  }

  // Map log(latency) to [0,1] range between 10s and 5min
  const minLog = Math.log(LOWER)
  const maxLog = Math.log(UPPER)
  const latencyLog = Math.log(latency_ms)
  const normalizedPos = (latencyLog - minLog) / (maxLog - minLog)

  // Map to color range index
  const step = colorRange.length - 1
  const pos = normalizedPos * step
  const floor = Math.floor(pos)
  const ceil = Math.ceil(pos)

  // Interpolate between colors
  const color = tinycolor(colorRange[floor])
    .mix(tinycolor(colorRange[ceil]), (pos - floor) * 100)
    .toHexString()

  return color
}
