import React, { Component } from 'react'
import PropTypes from 'prop-types'
import CircularProgress from '@material-ui/core/CircularProgress'
import common from '@material-ui/core/colors/common'
import grey from '@material-ui/core/colors/grey'
import BrokenImage from '@material-ui/icons/BrokenImage'

/**
 * Images are ugly until they're loaded. Materialize it with material image! It will fade in like the material image loading pattern suggests.
 * @see [Image loading patterns](https://material.io/guidelines/patterns/loading-images.html)
 */
export default class Image extends Component {
  constructor (props) {
    super(props)
    this.state = {
      imageError: false,
      imageLoaded: false
    }
  }

  componentWillReceiveProps (nextProps) {
    if (this.props.src !== nextProps.src) {
      this.setState({
        imageError: false,
        imageLoaded: false
      })
    }
  }

  getStyles () {
    const {
      aspectRatio,
      color,
      imageStyle,
      disableTransition,
      style
    } = this.props

    const imageTransition = !disableTransition && {
      opacity: this.state.imageLoaded ? 1 : 0,
      filterBrightness: this.state.imageLoaded ? 100 : 0,
      filterSaturate: this.state.imageLoaded ? 100 : 20,
      transition: 'filterBrightness 2.5s cubic-bezier(0.4, 0.0, 0.2, 1), filterSaturate 3s cubic-bezier(0.4, 0.0, 0.2, 1), opacity 2s cubic-bezier(0.4, 0.0, 0.2, 1)'
    }

    const styles = {
      root: {
        backgroundColor: color,
        paddingTop: `calc(1 / ${aspectRatio} * 100%)`,
        position: 'relative',
        ...style
      },
      image: {
        width: '100%',
        height: '100%',
        position: 'absolute',
        top: 0,
        left: 0,
        ...imageTransition,
        ...imageStyle
      }
    }

    return styles
  }

  handleLoadImage = () => {
    this.setState({ imageLoaded: true })
  }

  handleImageError = () => {
    if (this.props.src) {
      this.setState({ imageError: true })
    }
  }

  render () {
    const styles = this.getStyles()

    const {
      aspectRatio, // eslint-disable-line
      color, // eslint-disable-line
      disableError,
      disableSpinner,
      disableTransition, // eslint-disable-line
      errorIcon,
      imageStyle, // eslint-disable-line
      style, // eslint-disable-line
      loading,
      onClick,
      ...image
    } = this.props

    return (
      <div
        style={styles.root}
        onClick={onClick}
      >
        {image.src && <img
          {...image}
          style={styles.image}
          onLoad={this.handleLoadImage}
          onError={this.handleImageError}
        />}
        <div style={{
          width: '100%',
          height: '100%',
          position: 'absolute',
          top: 0,
          left: 0,
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          pointerEvents: 'none'
        }}>
          {!disableSpinner && !this.state.imageLoaded && !this.state.imageError && loading}
          {!disableError && this.state.imageError && errorIcon}
        </div>
      </div>
    )
  }
}

Image.defaultProps = {
  aspectRatio: 1,
  color: common.white,
  disableError: false,
  disableSpinner: false,
  disableTransition: false,
  errorIcon: <BrokenImage style={{ width: 48, height: 48, color: grey[300] }} />,
  loading: <CircularProgress size={48} />
}

Image.propTypes = {
  /** Specifies the URL of an image. */
  src: PropTypes.string.isRequired,
  /** Override aspect ratio. */
  aspectRatio: PropTypes.number,
  /** Override the background color. */
  color: PropTypes.string,
  /** Disables the error icon if set to true. */
  disableError: PropTypes.bool,
  /** Disables the loading spinner if set to true. */
  disableSpinner: PropTypes.bool,
  /** Disables the transition after load if set to true. */
  disableTransition: PropTypes.bool,
  /** Override the error icon. */
  errorIcon: PropTypes.node,
  /** Override the inline-styles of the image. */
  imageStyle: PropTypes.object,
  /** Override the loading component. */
  loading: PropTypes.node,
  /** Fired when the user clicks on the image happened. */
  onClick: PropTypes.func,
  /** Override the inline-styles of the root element. */
  style: PropTypes.object
}

@@ -1278,16 +1278,17 @@
 tness 2.
+2
 5s cubic
@@ -1372,17 +1372,19 @@
 opacity 
-2
+1.5
 s cubic-
@@ -2074,67 +2074,21 @@
 tio,
- // eslint-disable-line%0A      color, // eslint-disable-line
+%0A      color,
 %0A   
@@ -2150,39 +2150,16 @@
 nsition,
- // eslint-disable-line
 %0A      e
@@ -2189,67 +2189,21 @@
 yle,
- // eslint-disable-line%0A      style, // eslint-disable-line
+%0A      style,
 %0A   

Fix animation timings not matching the specifications. #27