import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Avatar from '@material-ui/core/Avatar';
import Chip from '@material-ui/core/Chip';
import AnnotationIcon from '@material-ui/icons/CommentSharp';
import SearchIcon from '@material-ui/icons/SearchSharp';
import classNames from 'classnames';
import 'intersection-observer'; // polyfill needed for Safari
import IntersectionObserver from '@researchgate/react-intersection-observer';
import MiradorCanvas from '../lib/MiradorCanvas';
import IIIFThumbnail from '../containers/IIIFThumbnail';

/**
 * Represents a WindowViewer in the mirador workspace. Responsible for mounting
 * OSD and Navigation
 */
export class GalleryViewThumbnail extends Component {
  /** */
  constructor(props) {
    super(props);

    this.myRef = React.createRef();
    this.state = { requestedAnnotations: false };

    this.handleSelect = this.handleSelect.bind(this);
    this.handleKey = this.handleKey.bind(this);
    this.handleIntersection = this.handleIntersection.bind(this);
  }

  // eslint-disable-next-line require-jsdoc
  componentDidMount() {
    const { selected } = this.props;
    if (selected) {
      this.myRef.current?.scrollIntoView(true);
    }
  }

  /** @private */
  handleSelect() {
    const {
      canvas, selected, setCanvas, focusOnCanvas,
    } = this.props;

    if (selected) {
      focusOnCanvas();
    } else {
      setCanvas(canvas.id);
    }
  }

  /** @private */
  handleKey(event) {
    const {
      canvas, setCanvas, focusOnCanvas,
    } = this.props;

    this.keys = {
      enter: 'Enter',
      space: ' ',
    };

    this.chars = {
      enter: 13,
      space: 32,
    };

    const enterOrSpace = (
      event.key === this.keys.enter
      || event.which === this.chars.enter
      || event.key === this.keys.space
      || event.which === this.chars.space
    );

    if (enterOrSpace) {
      focusOnCanvas();
    } else {
      setCanvas(canvas.id);
    }
  }

  /** */
  handleIntersection({ isIntersecting }) {
    const {
      annotationsCount,
      requestCanvasAnnotations,
    } = this.props;

    const { requestedAnnotations } = this.state;

    if (
      !isIntersecting
      || annotationsCount === undefined
      || annotationsCount > 0
      || requestedAnnotations) return;

    this.setState({ requestedAnnotations: true });
    requestCanvasAnnotations();
  }

  /**
   * Renders things
   */
  render() {
    const {
      annotationsCount, searchAnnotationsCount,
      canvas, classes, config, selected,
    } = this.props;

    const miradorCanvas = new MiradorCanvas(canvas);

    return (
      <IntersectionObserver onChange={this.handleIntersection}>
        <div
          key={canvas.index}
          className={
            classNames(
              classes.galleryViewItem,
              selected ? classes.selected : '',
              searchAnnotationsCount > 0 ? classes.hasAnnotations : '',
            )
          }
          onClick={this.handleSelect}
          onKeyUp={this.handleKey}
          ref={this.myRef}
          role="button"
          tabIndex={0}
        >
          <IIIFThumbnail
            resource={canvas}
            labelled
            variant="outside"
            maxWidth={config.width}
            maxHeight={config.height}
            style={{
              margin: '0 auto',
              maxWidth: `${Math.ceil(config.height * miradorCanvas.aspectRatio)}px`,
            }}
          >
            <div className={classes.chips}>
              { searchAnnotationsCount > 0 && (
                <Chip
                  avatar={(
                    <Avatar className={classes.avatar} classes={{ circle: classes.avatarIcon }}>
                      <SearchIcon fontSize="small" />
                    </Avatar>
                  )}
                  label={searchAnnotationsCount}
                  className={classNames(classes.searchChip)}
                  size="small"
                />
              )}
              { (annotationsCount || 0) > 0 && (
                <Chip
                  avatar={(
                    <Avatar className={classes.avatar} classes={{ circle: classes.avatarIcon }}>
                      <AnnotationIcon className={classes.annotationIcon} />
                    </Avatar>
                  )}
                  label={annotationsCount}
                  className={
                    classNames(
                      classes.annotationsChip,
                    )
                  }
                  size="small"
                />
              )}
            </div>
          </IIIFThumbnail>
        </div>
      </IntersectionObserver>
    );
  }
}

GalleryViewThumbnail.propTypes = {
  annotationsCount: PropTypes.number,
  canvas: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
  classes: PropTypes.objectOf(PropTypes.string).isRequired,
  config: PropTypes.shape({
    height: PropTypes.number,
    width: PropTypes.number,
  }),
  focusOnCanvas: PropTypes.func.isRequired,
  requestCanvasAnnotations: PropTypes.func,
  searchAnnotationsCount: PropTypes.number,
  selected: PropTypes.bool,
  setCanvas: PropTypes.func.isRequired,
};

GalleryViewThumbnail.defaultProps = {
  annotationsCount: undefined,
  config: {
    height: 100,
    width: null,
  },
  requestCanvasAnnotations: () => {},
  searchAnnotationsCount: 0,
  selected: false,
};