import {CanvasExpressiveIcon, CanvasIconTypes} from '@workday/canvas-expressive-icons-web';
import {createComponent} from '@workday/canvas-kit-react/common';
import {createStencil, cssVar, handleCsProp} from '@workday/canvas-kit-styling';
import {component} from '@workday/canvas-tokens-web';

import {Svg, SvgProps, resolveSize, svgStencil} from './Svg';

type ExpressiveSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';

export interface ExpressiveIconProps extends Omit<SvgProps, 'src' | 'type'> {
  /**
   * The accent color of the ExpressiveIcon.
   */
  accent?: string;
  /**
   * The outline color of the ExpressiveIcon.
   */
  color?: string;
  /**
   * The icon to display from `@workday/canvas-expressive-icons-web`.
   */
  icon: CanvasExpressiveIcon;
  /**
   * The size of the ExpressiveIcon in size variants or string / numeric (px) values.
   * **Expressive icon sizes**
   * - `xs`: 40px / 2.5rem
   * - `sm`: 48px / 3rem
   * - `md`: 56px / 3.5rem
   * - `lg`: 64px / 4rem
   * - `xl`: 96px / 6rem
   * @default `56px`
   */
  size?: ExpressiveSize | string | number;
}

export const expressiveIconStencil = createStencil({
  extends: svgStencil,
  vars: {
    /**
     * This will set the icon's outline color for the `.wd-expressive-fill` SVG layer.
     */
    color: '',
    /**
     * This will set the icon's accent color for the `.wd-expressive-accent` SVG layer.
     */
    accentColor: '',
  },
  base: ({size, accentColor, color}) => ({
    '& svg': {
      width: cssVar(size, component.legacy.expressiveIcon.size.md),
      height: cssVar(size, component.legacy.expressiveIcon.size.md),
    },
    '.wd-expressive .wd-expressive-fill': {
      fill: cssVar(color, component.legacy.expressiveIcon.color.fill),
    },
    '.wd-expressive .wd-expressive-accent': {
      fill: cssVar(accentColor, component.legacy.expressiveIcon.color.accent),
    },
    // for Windows high contrast desktop themes
    '@media (prefers-contrast: more)': {
      '.wd-expressive .wd-expressive-fill': {
        color: 'currentColor',
        fill: 'currentColor',
      },
      '.wd-expressive .wd-expressive-accent': {
        color: 'transparent',
        fill: 'transparent',
      },
    },
  }),
});

export const ExpressiveIcon = createComponent('span')({
  displayName: 'ExpressiveIcon',
  Component: ({accent, color, icon, size, ...elemProps}: ExpressiveIconProps, ref, Element) => {
    return (
      <Svg
        as={Element}
        src={icon}
        type={CanvasIconTypes.Expressive}
        ref={ref}
        {...handleCsProp(
          elemProps,
          expressiveIconStencil({
            size: resolveSize(size, component.legacy.expressiveIcon.size),
            color,
            accentColor: accent,
          })
        )}
      />
    );
  },
});
