import * as React from 'react';
import * as _omit from 'lodash.omit';
import {HTMLProps, PureComponent, ReactNode} from 'react';
import filterInvalidDOMProps from 'filter-invalid-dom-props';

export interface ImgProps extends HTMLProps<HTMLImageElement> {}

export interface ImgState {
  imageSrc: string;
}

export class Img extends PureComponent<ImgProps, ImgState> {
  image: HTMLImageElement;

  state: ImgState = {
    imageSrc: null,
  };

  componentDidMount() {
    const {src} = this.props;
    this.image = new Image();

    if (src) {
      this.setDisplayImage(src);
    }
  }

  componentWillReceiveProps(nextProps: ImgProps) {
    if (nextProps.src !== this.props.src) {
      this.setDisplayImage(nextProps.src);
    }
  }

  componentWillUnmount() {
    if (this.image) {
      this.image.onerror = null;
      this.image.onload = null;
      this.image = null;
    }
  }

  setDisplayImage = (imageSrc: string) => {
    this.image.onerror = () => {
      this.setState({imageSrc: null}, this.props.onError as any);
    };

    this.image.onload = () => {
      if (this.image.naturalWidth === 1) {
        this.setState({imageSrc: null}, this.props.onError as any);
      } else {
        this.setState({imageSrc}, this.props.onLoad as any);
      }
    };

    this.image.src = imageSrc || '';
  }

  render() {
    const {imageSrc} = this.state;
    const {...otherProps} = _omit(this.props, ['src']);

    if (imageSrc) {
      return (
        <img
          {...filterInvalidDOMProps(otherProps)}
          src={imageSrc}
        />
      );
    }

    return null;
  }
}
