import tinycolor from "tinycolor2";

function hexToRgb(hex: string) {
  const sanitizedHex = hex.replace(/##/g, "#");
  const colorParts = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(
    sanitizedHex
  );

  if (!colorParts) {return null}

  const [, r, g, b] = colorParts;

  return {
    r: parseInt(r, 16),
    g: parseInt(g, 16),
    b: parseInt(b, 16)
  }
}

function rgbToHex(r: number, g: number, b: number) {
  const toHex = (c: number) => `0${c.toString(16)}`.slice(-2);
  return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
}

const lighten = (hex: string, intensity: number) => {
  const color = hexToRgb(`#${hex}`);

  if (!color) {return ""}

  const r = Math.round(color.r + (255 - color.r) * intensity);
  const g = Math.round(color.g + (255 - color.g) * intensity);
  const b = Math.round(color.b + (255 - color.b) * intensity);

  return rgbToHex(r, g, b);
}

const darken = (hex: string, intensity: number) => {
  const color = hexToRgb(hex);

  if (!color) {return ""}

  const r = Math.round(color.r * intensity);
  const g = Math.round(color.g * intensity);
  const b = Math.round(color.b * intensity);

  return rgbToHex(r, g, b);
}

export const generatePalette = (baseColor: string):Palette => {
  // 颜色转换
  baseColor = tinycolor(baseColor).toHexString();

  // const intensityMap: IntensityMap = {
  //   50: 0.95,
  //   100: 0.9,
  //   200: 0.75,
  //   300: 0.6,
  //   400: 0.3,
  //   600: 0.9,
  //   700: 0.75,
  //   800: 0.6,
  //   900: 0.49
  // };

  const intensityMap: IntensityMap = {
    50: 0.9,
    100: 0.8,
    200: 0.6,
    300: 0.4,
    400: 0.2,
    600: 0.8,
    700: 0.6,
    800: 0.4,
    900: 0.2,
    950: 0.1
  };

  return {
    DEFAULT: baseColor,
    50: lighten(baseColor, intensityMap[50]),
    100: lighten(baseColor, intensityMap[100]),
    200: lighten(baseColor, intensityMap[200]),
    300: lighten(baseColor, intensityMap[300]),
    400: lighten(baseColor, intensityMap[400]),
    500: baseColor,
    600: darken(baseColor, intensityMap[600]),
    700: darken(baseColor, intensityMap[700]),
    800: darken(baseColor, intensityMap[800]),
    900: darken(baseColor, intensityMap[900]),
    950: darken(baseColor, intensityMap[950]),
  };
}
