import {hslToHex} from './utils'

// ported from bluesky alf hsl scale

export const COLOR_STOPS = [
  0, 0.05, 0.1, 0.15, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.85, 0.9,
  0.95, 1,
]

export const generateScale = (
  start: number,
  end: number,
): number[] => {
  const range = end - start
  return COLOR_STOPS.map((stop) => start + range * stop)
}

const lightnessScale = generateScale(6, 100)

// warm sepia neutrals; yellow-green accent derived from our `yellow_green`
// (#9acd32 ≈ hsl(80, 61%, 50%))
export const NEUTRAL_HUE = 40
export const ACCENT_HUE = 80
export const POSITIVE_HUE = 152
export const NEGATIVE_HUE = 8

const SCALE_KEYS = [
  25, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950, 975,
] as const

type ScaleKey = (typeof SCALE_KEYS)[number]
export type ColorRamp = Record<ScaleKey, string>

// brand ramps share one saturation; lightness descends 25 (lightest) -> 975
const BRAND_LIGHTNESS = [
  97, 95, 90, 80, 70, 60, 53, 42, 34, 26, 18, 10, 7,
]

export const brandRamp = (
  hue: number,
  saturation: number,
): ColorRamp =>
  Object.fromEntries(
    SCALE_KEYS.map((key, i) => [
      key,
      hslToHex(hue, saturation, BRAND_LIGHTNESS[i]!),
    ]),
  ) as ColorRamp

// neutrals track the lightness scale and taper saturation: warm at the
// cream/charcoal ends, quieter through the mid greys
const NEUTRAL_SATURATION = [
  24, 22, 20, 18, 16, 15, 14, 14, 16, 20, 24, 26, 28,
]

export const neutralRamp = (hue: number): ColorRamp =>
  Object.fromEntries(
    SCALE_KEYS.map((key, i) => [
      key,
      hslToHex(hue, NEUTRAL_SATURATION[i]!, lightnessScale[13 - i]!),
    ]),
  ) as ColorRamp

// solid surface / ink extremes beyond the 25..975 ramp
export const neutralEnds = (hue: number) => ({
  lightest: hslToHex(
    hue,
    NEUTRAL_SATURATION[0]!,
    lightnessScale[14]!,
  ),
  darkest: hslToHex(hue, NEUTRAL_SATURATION[12]!, lightnessScale[0]!),
})

// dark themes read the ramp inverted (25 <-> 975)
export const reverseRamp = (ramp: ColorRamp): ColorRamp =>
  Object.fromEntries(
    SCALE_KEYS.map((key, i) => [key, ramp[SCALE_KEYS[12 - i]!]]),
  ) as ColorRamp

export const prefixRamp = (
  prefix: string,
  ramp: ColorRamp,
): Record<string, string> =>
  Object.fromEntries(
    Object.entries(ramp).map(([key, value]) => [
      `${prefix}_${key}`,
      value,
    ]),
  )
