import React, { useCallback } from "react";
import cn from "classnames";
import { getPressedKey, KEYS } from "../utils/keyboard";

export interface IIconProps {
  id: string;
  viewBox?: string;
  size?: "xs" | "sm" | "md" | "lg" | "xl" | "xxl";
  // prettier-ignore
  color?: "primary" | "secondary" | "success" | "danger" | "warning" | "info" | "light" | "dark" | "white" | "muted";
  currentColor?: boolean;
  width?: number;
  height?: number;
  className?: string;
  onClick?(event: React.SyntheticEvent | React.KeyboardEvent): void;
  title?: string;
  style?: {};
  "data-testid"?: string;
  x?: number;
  y?: number;
}

function getIconSize(
  size: IIconProps["size"],
  width: IIconProps["width"],
  height: IIconProps["height"]
) {
  switch (size) {
    case "xs":
      return { width: 12, height: 12 };
    case "sm":
      return { width: 16, height: 16 };
    case "md":
      return { width: 24, height: 24 };
    case "lg":
      return { width: 28, height: 28 };
    case "xl":
      return { width: 32, height: 32 };
    case "xxl":
      return { width: 64, height: 64 };
    default:
      return { width, height };
  }
}

function getIconColor(color: IIconProps["color"]) {
  if (!color) {
    return;
  }
  return `text-${color}`;
}

const Icon: React.FC<IIconProps> = React.forwardRef(
  (props: IIconProps, ref: React.Ref<SVGSVGElement>) => {
    const {
      id,
      viewBox,
      width,
      height,
      size,
      color,
      currentColor,
      className,
      onClick,
      style,
      "data-testid": dataTestId,
      title,
      x,
      y
    } = props;

    const colorClass = getIconColor(color);
    const onKeyPress = useCallback(
      (e: React.KeyboardEvent) => {
        if (!onClick) {
          return;
        }
        const key = getPressedKey(e);
        if (key === KEYS.Enter || key === KEYS.Space) {
          onClick(e);
        }
      },
      [onClick]
    );

    if (onClick && !title) {
      console.warn("Warning: HoneyUI React Icon 'title' must be provided with onClick event.");
    }

    const testId = dataTestId || `honeyui-icon-${id}`;
    return (
      <svg
        role={onClick ? "button" : "img"}
        data-testid={testId}
        viewBox={viewBox}
        tabIndex={onClick ? 0 : undefined}
        className={cn(`honeyui-icon honeyui-icon--${id}`, className, {
          [`${colorClass}`]: !currentColor && colorClass,
          "cursor-pointer": !!onClick
        })}
        {...getIconSize(size, width, height)}
        onClick={onClick ? onClick : undefined}
        onKeyPress={onClick ? onKeyPress : undefined}
        aria-label={onClick ? title : undefined}
        ref={ref}
        style={currentColor ? { ...style, fill: "currentColor" } : style}
        x={x}
        y={y}
      >
        {title ? <title data-testid={`${testId}-title`}>{title}</title> : null}
        <use xlinkHref={`#${id}`} />
      </svg>
    );
  }
);

Icon.displayName = "Icon";
Icon.defaultProps = {
  color: "dark",
  currentColor: false
};
export default Icon;
