import { Component } from 'react';
import PropTypes from 'prop-types';
import Chip from '@mui/material/Chip';
import MenuList from '@mui/material/MenuList';
import MenuItem from '@mui/material/MenuItem';
import ListItemText from '@mui/material/ListItemText';
import Typography from '@mui/material/Typography';
import SearchIcon from '@mui/icons-material/SearchSharp';
import TextField from '@mui/material/TextField';
import SanitizedHtml from '../containers/SanitizedHtml';
import { ScrollTo } from './ScrollTo';
import AnnotationManifestsAccordion from '../containers/AnnotationManifestsAccordion';
import { filterAnnotation } from '../helper/utils';
import { MiradorMenuButton } from './MiradorMenuButton';

/**
 * CanvasAnnotations ~
*/
export class CanvasAnnotations extends Component {
  /**
   * constructor -
   */
  constructor(props) {
    super(props);

    this.handleClick = this.handleClick.bind(this);
    this.handleAnnotationHover = this.handleAnnotationHover.bind(this);
    this.handleAnnotationBlur = this.handleAnnotationBlur.bind(this);
    this.handleAnnotationSearch = this.handleAnnotationSearch.bind(this);

    this.state = { };
  }

  /**
   * Handle click event of an annotation.
  */
  handleClick(event, annotation) {
    const {
      deselectAnnotation, selectAnnotation, selectedAnnotationId, windowId,
    } = this.props;

    if (selectedAnnotationId === annotation.id) {
      deselectAnnotation(windowId, annotation.id);
    } else {
      selectAnnotation(windowId, annotation.id);
    }
  }

  /** */
  handleAnnotationHover(annotation) {
    const { hoverAnnotation, windowId } = this.props;

    hoverAnnotation(windowId, [annotation.id]);
  }

  /** */
  handleAnnotationBlur() {
    const { hoverAnnotation, windowId } = this.props;

    hoverAnnotation(windowId, []);
  }

  /** */
  handleAnnotationSearch(event) {
    this.setState({ inputSearch: event.target.value });
  }

  /**
   * Returns the rendered component
  */
  render() {
    const {
      annotations, autoScroll, index, label, selectedAnnotationId, t, totalSize,
      listContainerComponent, htmlSanitizationRuleSet, hoveredAnnotationIds,
      containerRef,
    } = this.props;
    if (annotations.length === 0) return null;

    const { inputSearch } = this.state;

    if (inputSearch != undefined && inputSearch !== '') {
      annotations = filterAnnotation(annotations, inputSearch);
    }

    const annotationCount = annotations.length;

    return (
      <>
        <Typography sx={{ paddingLeft: 2, paddingRight: 1, paddingTop: 2 }} variant="overline">
          {t('annotationCanvasLabel', { context: `${index + 1}/${totalSize}`, label })}
        </Typography>

        <div sx={theme => ({
          background: theme.palette.background.paper,
          borderBottom: `.5px solid ${theme.palette.section_divider}`,
          marginBottom: theme.spacing(1),
          padding: theme.spacing(0, 1, 1, 1),
          position: 'sticky',
          top: 0,
          zIndex: 10,
        })}
        >
          <TextField
            label={t('searchPlaceholderAnnotation')}
            onChange={this.handleAnnotationSearch}
            sx={{
              width: '100%',
            }}
            InputProps={{
              endAdornment: (
                <div style={{
                  position: 'absolute',
                  right: 0,
                }}
                >
                  <MiradorMenuButton aria-label={t('searchAnnotationTooltip')} type="submit">
                    <SearchIcon />
                  </MiradorMenuButton>
                </div>
              ),
            }}
          />
        </div>
        <MenuList autoFocusItem variant="selectedMenu">
          {
            annotations.map(annotation => (
              <ScrollTo
                containerRef={containerRef}
                key={`${annotation.id}-scroll`}
                offsetTop={96} // offset for the height of the form above
                scrollTo={autoScroll ? (selectedAnnotationId === annotation.id) : false}
              >
                <MenuItem
                  component={listContainerComponent}
                  variant="multiline"
                  divider
                  sx={{
                    '&:hover,&:focus': {
                      backgroundColor: 'action.hover',
                    },
                    backgroundColor: hoveredAnnotationIds.includes(annotation.id) ? 'action.hover' : '',
                  }}
                  key={annotation.id}
                  annotationid={annotation.id}
                  selected={selectedAnnotationId === annotation.id}
                  onClick={e => this.handleClick(e, annotation)}
                  onFocus={() => this.handleAnnotationHover(annotation)}
                  onBlur={this.handleAnnotationBlur}
                  onMouseEnter={() => this.handleAnnotationHover(annotation)}
                  onMouseLeave={this.handleAnnotationBlur}
                >
                  <ListItemText primaryTypographyProps={{ variant: 'body2' }}>
                    <SanitizedHtml
                      ruleSet={htmlSanitizationRuleSet}
                      htmlString={annotation.content}
                    />
                    <div>
                      {
                        annotation.tags.map(tag => (
                          <Chip
                            size="small"
                            variant="outlined"
                            label={tag}
                            id={tag}
                            sx={theme => ({
                              backgroundColor: theme.palette.background.paper,
                              marginRight: theme.spacing(0.5),
                              marginTop: theme.spacing(1),
                            })}
                            key={tag.toString()}
                          />
                        ))
                      }
                      <AnnotationManifestsAccordion
                        annotation={annotation}
                        t={t}
                      />
                    </div>
                  </ListItemText>
                </MenuItem>
              </ScrollTo>
            ))
          }
          {annotations.length == 0
            && (
              <MenuItem>
                <Typography>
                  {t('noAnnotationFound')}
                </Typography>
              </MenuItem>
            )}
        </MenuList>
        <div sx={ theme => ({
          background: theme.palette.background.paper,
          borderTop: `.5px solid ${theme.palette.section_divider}`,
          bottom: 0,
          paddingBottom: theme.spacing(1),
          paddingLeft: theme.spacing(2),
          paddingRight: theme.spacing(1),
          paddingTop: theme.spacing(2),
          position: 'sticky',
        })}
        >
          <Typography component="p" variant="subtitle2">{t('showingNumAnnotations', { count: annotationCount, number: annotationCount })}</Typography>
        </div>
      </>
    );
  }
}

CanvasAnnotations.propTypes = {
  annotations: PropTypes.arrayOf(
    PropTypes.shape({
      content: PropTypes.string.isRequired,
      id: PropTypes.string.isRequired,
    }),
  ),
  autoScroll: PropTypes.bool,
  containerRef: PropTypes.oneOfType([
    PropTypes.func,
    PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
  ]),
  deselectAnnotation: PropTypes.func.isRequired,
  hoverAnnotation: PropTypes.func.isRequired,
  hoveredAnnotationIds: PropTypes.arrayOf(PropTypes.string),
  htmlSanitizationRuleSet: PropTypes.string,
  index: PropTypes.number.isRequired,
  label: PropTypes.string.isRequired,
  listContainerComponent: PropTypes.elementType,
  selectAnnotation: PropTypes.func.isRequired,
  selectedAnnotationId: PropTypes.string,
  t: PropTypes.func.isRequired,
  totalSize: PropTypes.number.isRequired,
  windowId: PropTypes.string.isRequired,
};
CanvasAnnotations.defaultProps = {
  annotations: [],
  autoScroll: true,
  containerRef: undefined,
  hoveredAnnotationIds: [],
  htmlSanitizationRuleSet: 'iiif',
  listContainerComponent: 'li',
  selectedAnnotationId: undefined,
};