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 { MODERN_TOKEN_MAP } from '../shared/constants';
import { type ModernTokenSpec } from '../shared/types';
import { getColorType } from '../shared/utils';

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

/** Neutral text + divider colors, identical across all modern accents. */
const buildModernNeutrals = (theme: Theme) => ({
  subtitle: theme.palette.newBase?.grey[950],
  description: theme.palette.newBase?.grey[950],
  headerDivider: theme.palette.newBase?.grey[200],
});

const resolveModernCommunityPaint = (
  accentHex: string,
  theme: Theme,
): ModernPaint => {
  const isLight = getColorType(accentHex) === 'light';
  const titleColor = isLight
    ? darken(accentHex, 0.38)
    : darken(accentHex, 0.15);
  const accentColor = isLight ? accentHex : lighten(accentHex, 0.2);
  return {
    titleColor,
    gradientTop: titleColor,
    gradientBottom: accentColor,
    accentColor,
    ...buildModernNeutrals(theme),
  };
};

const resolveModernTokenPaint = (
  spec: ModernTokenSpec,
  theme: Theme,
): ModernPaint | undefined => {
  const newBase = theme.palette.newBase;
  if (!newBase) return undefined;
  const ramp = newBase[spec.hue];
  return {
    titleColor: ramp[spec.titleColor],
    gradientTop:
      spec.gradientTop === 'white' ? newBase.white : ramp[spec.gradientTop],
    gradientBottom:
      spec.gradientBottom === 'white'
        ? newBase.white
        : ramp[spec.gradientBottom],
    accentColor: ramp[spec.accentColor],
    ...buildModernNeutrals(theme),
  };
};

/** Resolves the full modern paint from the accent color enum and hex. */
export const resolveModernPaint = (
  accentColor: LearningCertificateColor,
  accentHex: string,
  theme: Theme,
): ModernPaint => {
  if (accentColor === 'COMMUNITY') {
    return resolveModernCommunityPaint(accentHex, theme);
  }
  const spec = MODERN_TOKEN_MAP[accentColor];
  return (
    resolveModernTokenPaint(spec, theme) ??
    resolveModernCommunityPaint(accentHex, theme)
  );
};
