import React, { memo } from "react";

import { pxToRem } from "../../utils";
import { colors, styled } from "../../theme";
import type { SvgProps } from "./types";
import type { ColorKey, CSS } from "../../theme";

export const ICON_SIZES = {
  s: pxToRem(12),
  m: pxToRem(16),
  l: pxToRem(24),
  xl: pxToRem(32),
};

export interface IconProps {
  size?: number | keyof typeof ICON_SIZES;
  color?: ColorKey;
  background?: ColorKey;
}

type EnhancedIcon<T extends SvgProps> = React.FC<
  Omit<Partial<Pick<T, keyof SvgProps>>, "color" | "background"> &
    Omit<T, keyof SvgProps> &
    IconProps & { css?: CSS }
>;

export const withSharedIconProps = <T extends SvgProps>(
  WrappedIcon: React.FC<T>
): EnhancedIcon<T> => {
  const EnhancedIcon: EnhancedIcon<T> = memo((props) => {
    const {
      size = "m",
      color = "$currentColor",
      background = "$light-chromia-dark",
      strokeWidth = pxToRem(1.5),
      width = typeof size === "number" ? size : ICON_SIZES[size],
      height = typeof size === "number" ? size : ICON_SIZES[size],
      css,
      ...rest
    } = props;
    const token = color.replace("$", "") as keyof typeof colors;
    const backgroundToken = background.replace("$", "") as keyof typeof colors;

    const enhancedProps = {
      width,
      height,
      color: colors[token],
      background: colors[backgroundToken],
      strokeWidth,
      ...rest,
    } as T;
    const StyledIcon = styled(WrappedIcon, css ? css : {}) as React.FC<T>;
    return <StyledIcon {...enhancedProps} />;
  });

  const displayName = WrappedIcon.displayName || WrappedIcon.name;
  EnhancedIcon.displayName = displayName;
  return EnhancedIcon;
};
