import {createComponent} from '@workday/canvas-kit-react/common';
import {createStencil, cssVar, handleCsProp} from '@workday/canvas-kit-styling';
import {CanvasIconTypes, CanvasSystemIcon} from '@workday/canvas-system-icons-web';
import {component} from '@workday/canvas-tokens-web';
import {CanvasSystemIcon as LegacyCanvasSystemIcon} from '@workday/design-assets-types';

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

type SystemSize = 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';

export interface SystemIconProps extends Omit<SvgProps, 'src' | 'type'> {
  /**
   * The accent color of the SystemIcon. This overrides `color`.
   */
  accent?: string;
  /**
   * The background color of the SystemIcon.
   */
  background?: string;
  /**
   * The color of the SystemIcon. This defines `accent` and `fill`. `color` may be overwritten by `accent` and `fill`.
   */
  color?: string;
  /**
   * The icon to display from `@workday/canvas-system-icons-web`.
   */
  icon: CanvasSystemIcon | LegacyCanvasSystemIcon;
  /**
   * The size of the SystemIcon in size variants or string / numeric (px) values.
   * **System icon sizes**
   * - `xxs`: 14px / 0.875rem
   * - `xs`: 16px / 1rem
   * - `sm`: 18px / 1.125rem
   * - `md`: 20px / 1.25rem
   * - `lg`: 24px / 1.5rem
   * - `xl`: 32px / 2rem
   * @default `24px`
   */
  size?: SystemSize | string | number;
}

export const systemIconStencil = createStencil({
  extends: svgStencil,
  vars: {
    /**
     * This will set the icon's color (both `.wd-icon-fill` and `.wd-icon-accent` SVG layers). Most
     * of the time, this is the only color you need to change. Icons also have an accent layer. If you
     * wish to change the accent layer independently, also set the `accentColor` variable
     */
    color: '',
    /**
     * This will set the icon's accent color for the `.wd-icon-accent` SVG layer.
     */
    accentColor: '',
    /**
     * This will set the icon's background color for the `.wd-icon-background` SVG layer.
     */
    backgroundColor: '',
  },
  base: ({size, accentColor, backgroundColor, color}) => ({
    '& svg': {
      width: cssVar(size, component.legacy.systemIcon.size.lg),
      height: cssVar(size, component.legacy.systemIcon.size.lg),
    },
    '.wd-icon .wd-icon-fill': {
      fill: cssVar(color, component.legacy.systemIcon.color.fill),
    },
    '.wd-icon .wd-icon-accent, & .wd-icon-accent2': {
      fill: cssVar(accentColor, cssVar(color, component.legacy.systemIcon.color.accent)),
    },
    '.wd-icon .wd-icon-background': {
      fill: cssVar(backgroundColor, 'transparent'),
    },
    // for Windows high contrast desktop themes
    '@media (prefers-contrast: more)': {
      '.wd-icon .wd-icon-fill, .wd-icon .wd-icon-accent': {
        color: 'currentColor',
        fill: 'currentColor',
      },
    },
  }),
  // Keeps parent stencil `ME` inferred as `{}` so extending stencils keep correct boolean modifier typings.
  modifiers: {},
});

export const SystemIcon = createComponent('span')({
  displayName: 'SystemIcon',
  Component: (
    {accent, background, color, icon, size, ...elemProps}: SystemIconProps,
    ref,
    Element
  ) => {
    return (
      <Svg
        as={Element}
        src={icon}
        type={CanvasIconTypes.System}
        ref={ref}
        {...handleCsProp(
          elemProps,
          systemIconStencil({
            size: resolveSize(size, component.legacy.systemIcon.size),
            color,
            accentColor: accent,
            backgroundColor: background,
          })
        )}
      />
    );
  },
});
