import { darken, lighten } from '@mui/system/colorManipulator';
import { type Theme } from '@material-hu/mui/styles';

import { type LearningCertificateColor } from 'src/pages/dashboard/Learning/Settings/Certificates/types';

import { CLASSIC_TOKEN_MAP } from '../shared/constants';
import { type ClassicTokenSpec } from '../shared/types';
import { getColorType } from '../shared/utils';

import { type ClassicPaint } from './types';

const resolveClassicCommunityPaint = (
  accentHex: string,
  theme: Theme,
): ClassicPaint => {
  const isLight = getColorType(accentHex) === 'light';
  if (isLight) {
    return {
      bg: lighten(accentHex, 0.86),
      border1: darken(accentHex, 0.42),
      border2: lighten(accentHex, 0.41),
      border3: accentHex,
      text: darken(accentHex, 0.62),
      bodyText: theme.palette.newBase?.black ?? theme.palette.common.black,
      wordmarkInvert: false,
    };
  }
  return {
    bg: darken(accentHex, 0.85),
    border1: lighten(accentHex, 0.21),
    border2: darken(accentHex, 0.31),
    border3: lighten(accentHex, 0.71),
    text: lighten(accentHex, 0.85),
    bodyText: theme.palette.newBase?.white ?? theme.palette.common.white,
    wordmarkInvert: true,
  };
};

const resolveClassicTokenPaint = (
  spec: ClassicTokenSpec,
  theme: Theme,
): ClassicPaint | undefined => {
  const newBase = theme.palette.newBase;
  if (!newBase) return undefined;
  const ramp = newBase[spec.hue];
  return {
    bg: spec.bg === 'white' ? newBase.white : ramp[spec.bg],
    border1: ramp[spec.border1],
    border2: ramp[spec.border2],
    border3: ramp[spec.border3],
    text: ramp[spec.text],
    bodyText: spec.isDark ? newBase.grey[50] : newBase.grey[950],
    wordmarkInvert: spec.isDark,
  };
};

/** Resolves the full classic paint from the accent color enum and hex. */
export const resolveClassicPaint = (
  accentColor: LearningCertificateColor,
  accentHex: string,
  theme: Theme,
): ClassicPaint => {
  if (accentColor === 'COMMUNITY') {
    return resolveClassicCommunityPaint(accentHex, theme);
  }
  const spec = CLASSIC_TOKEN_MAP[accentColor];
  return (
    resolveClassicTokenPaint(spec, theme) ??
    resolveClassicCommunityPaint(accentHex, theme)
  );
};
