import React, {
  useState, useMemo, Children, cloneElement,
} from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { modifierCSS } from '../../../helpers';

const propTypes = {
  children: PropTypes.element,
  className: PropTypes.string,
  defaultClassName: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
  alt: PropTypes.string,
  src: PropTypes.string,
  size: PropTypes.oneOf(['', 'xxs', 'xs', 'sm', 'lg', 'xl', 'xxl']),
  ratio: PropTypes.oneOf(['', '3/4', '16/9', '2/1', '1/2', '4/3']),
  shadow: PropTypes.oneOf(['', '100', '200', '300', '400', '500', '600', 100, 200, 300, 400, 500, 600]),
  /**
   * The component used for the root node.
   * Either a string to use a DOM element or a component.
   */
  tag: PropTypes.elementType,
};

const defaultProps = {
  children: PropTypes.element,
  className: '',
  defaultClassName: 'sui-a-thumbnail',
  src: '',
  alt: '',
  size: '',
  ratio: '',
  shadow: '',
  tag: 'div',
};

export const Thumbnail = React.forwardRef(({
  children,
  className,
  defaultClassName,
  src,
  alt,
  size,
  ratio,
  shadow,
  tag: Tag,
  ...attributes
}, ref) => {
  const [isLoading, setIsLoading] = useState(true);
  const classRatio = ratio.split('/').join('_');

  const classes = classnames(
    defaultClassName,
    modifierCSS(size),
    modifierCSS(shadow, 'shadow'),
    modifierCSS(classRatio, 'ratio'),
    isLoading ? 'as--init-loader' : '',
    className
  );

  const handleStopLoading = () => setIsLoading(false);

  const content = useMemo(() => {
    // The component doesn't have any children and a src is passed
    if (src && !Children.count(children)) {
      return <img src={src} alt={alt} onLoad={handleStopLoading} />;
    }

    // Pass the handleStopLoading method to the onLoad event handler if
    // an img is passed as a child to Thumbnail
    if (children && React.isValidElement(children) && children.type === 'img') {
      return Children.map(children, (child) => cloneElement(child, { onLoad: handleStopLoading }));
    }

    handleStopLoading();

    return children;
  }, [children, src]);

  return (
    <Tag {...attributes} className={classes} ref={ref}>
      {content}
    </Tag>
  );
});

Thumbnail.propTypes = propTypes;
Thumbnail.defaultProps = defaultProps;
