import React, { useState, useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import { withTheme } from '../styles';

import GalleryContainerStyled, { GalleryButton } from './Gallery.style';
import Flex from '../Flex';

const GalleryComponent = ({ theme, id, children }) => {
  const firstBreakpoint = theme.space.body.container[0];
  const doubleSpace = parseInt(firstBreakpoint.replace('px', ''), 10) * 2;
  const mainRef = useRef();

  const [scrollLeft, setScrollLeft] = useState(0);
  const [clientWidth, setClientWidth] = useState(0);
  const [scrollWidth, setScrollWidth] = useState(0);

  /* istanbul ignore next */
  const scroll = (orientation = 1) => {
    const scrollValue =
      mainRef.current.scrollWidth / mainRef.current.childElementCount;
    mainRef.current.scrollLeft += scrollValue * orientation;
  };

  /* istanbul ignore next */
  useEffect(() => {
    const { current } = mainRef;

    const handleResize = () => {
      if (current && current.scrollWidth && current.clientWidth) {
        setScrollLeft(current.scrollLeft);
        setClientWidth(current.clientWidth);
        setScrollWidth(current.scrollWidth);
      }
    };

    handleResize();
    window.addEventListener('resize', handleResize);

    if (document.querySelector(`#${id}`)) {
      document.querySelector(`#${id}`).addEventListener('scroll', handleResize);
    }

    return () => {
      window.removeEventListener('resize', handleResize);
      if (document.querySelector(`#${id}`)) {
        document
          .querySelector(`#${id}`)
          .removeEventListener('scroll', handleResize);
      }
    };
  });

  /* istanbul ignore next */
  const navigationButtons = () => {
    if (scrollWidth > clientWidth) {
      return (
        <Flex justifyContent="flex-end" mt={theme.space.base}>
          <GalleryButton
            className="gallery-right-button"
            disabled={scrollLeft <= 0}
            onClick={
              /* istanbul ignore next */
              () => {
                scroll(-1);
              }
            }
          >
            <span>
              <svg viewBox="0 0 18 18" role="img" aria-label="Previous">
                <path
                  d="m13.7 16.29a1 1 0 1 1 -1.42 1.41l-8-8a1 1 0 0 1 0-1.41l8-8a1 1 0 1 1 1.42 1.41l-7.29 7.29z"
                  fillRule="evenodd"
                />
              </svg>
            </span>
          </GalleryButton>
          <GalleryButton
            className="gallery-left-button"
            disabled={scrollLeft + clientWidth >= scrollWidth}
            onClick={
              /* istanbul ignore next */
              () => {
                scroll();
              }
            }
          >
            <span>
              <svg
                viewBox="0 0 18 18"
                role="img"
                aria-label="Previous"
                focusable="false"
              >
                <path
                  d="m4.29 1.71a1 1 0 1 1 1.42-1.41l8 8a1 1 0 0 1 0 1.41l-8 8a1 1 0 1 1 -1.42-1.41l7.29-7.29z"
                  fillRule="evenodd"
                />
              </svg>
            </span>
          </GalleryButton>
        </Flex>
      );
    }

    return false;
  };

  return (
    <>
      <GalleryContainerStyled
        id={id}
        ref={mainRef}
        flexWrap="nowrap"
        overflowX="auto"
        style={{
          scrollSnapType: 'x mandatory',
          WebkitOverflowScrolling: 'touch',
        }}
        m={[`0 -${firstBreakpoint}`, '0']}
        width={[`calc(100% + ${doubleSpace}px)`, 1]}
      >
        {children}
      </GalleryContainerStyled>
      {navigationButtons()}
    </>
  );
};

GalleryComponent.propTypes = {
  children: PropTypes.oneOfType([
    PropTypes.node,
    PropTypes.arrayOf(PropTypes.node),
  ]).isRequired,
  theme: PropTypes.objectOf(Object),
  id: PropTypes.string.isRequired,
};

GalleryComponent.defaultProps = {
  theme: {},
};

GalleryComponent.displayName = 'Gallery';

export default withTheme(GalleryComponent);
