//@flow
import React, { Component } from 'react'
import type { ElementRef } from 'react'

type Props = { src: string, alt: string }

type State = { source?: string }

export default class LazyImage extends Component<Props, State> {
  state = {}
  observer: IntersectionObserver
  node: HTMLImageElement

  setRef: ElementRef<'img'> = (node: HTMLImageElement): void => {
    this.node = node
  }

  componentDidMount() {
    const { updateSourceIfElementIsInView } = this

    if (typeof IntersectionObserver === 'undefined') {
      this.setImageSourceFromProps()
      return
    }

    //$FlowFixMe: signature is wrong in flow
    this.observer = new IntersectionObserver(updateSourceIfElementIsInView)
    this.observer.observe(this.node)
  }

  updateSourceIfElementIsInView = (
    entries: Array<IntersectionObserverEntry>,
  ) => {
    const [elementEntry] = entries

    if (elementEntry.isIntersecting) {
      this.setImageSourceFromProps()
      this.observer.disconnect()
    }
  }

  setImageSourceFromProps() {
    const { src: source } = this.props
    this.setState({ source })
  }

  render() {
    const { setRef } = this
    // eslint-disable-next-line no-unused-vars
    const { src, alt, ...restProps } = this.props
    const { source } = this.state
    return <img {...restProps} alt={alt} src={source} ref={setRef} />
  }
}