import PropTypes from 'prop-types';
import React, { useEffect, useState } from 'react';
import Slugger from 'github-slugger';
import cn from 'classnames';
import striptags from 'striptags';
import styled from '@emotion/styled';
import useWindowScroll from 'react-use/lib/useWindowScroll';
import useWindowSize from 'react-use/lib/useWindowSize';
import { colors } from 'gatsby-theme-apollo-core';
import { trackCustomEvent } from 'gatsby-plugin-google-analytics';

const StyledList = styled.ul({
  marginLeft: 0,
  marginBottom: 48,
  overflow: 'auto'
});

const StyledListItem = styled.li({
  listStyle: 'none',
  fontSize: '1rem',
  lineHeight: 'inherit',
  '&.active': {
    color: colors.primary,
    fontWeight: 'bold'
  },
  a: {
    color: 'inherit',
    textDecoration: 'none',
    ':hover': {
      opacity: colors.hoverOpacity
    }
  }
});

function handleHeadingClick(event) {
  trackCustomEvent({
    category: 'Section Nav',
    action: 'Heading click',
    label: event.target.innerText
  });
}

export default function SectionNav(props) {
  const { y } = useWindowScroll();
  const { width, height } = useWindowSize();
  const [offsets, setOffsets] = useState([]);

  const { contentRef, imagesLoaded } = props;
  useEffect(() => {
    const headings = contentRef.current.querySelectorAll(
      [1, ...props.headings.map(heading => heading.depth)]
        .map(depth => 'h' + depth)
        .toString()
    );
    setOffsets(
      Array.from(headings)
        .map(heading => {
          const anchor = heading.querySelector('a');
          if (!anchor) {
            return null;
          }

          return {
            id: heading.id,
            offset: heading.offsetTop + anchor.offsetTop
          };
        })
        .filter(Boolean)
    );
  }, [width, height, contentRef, imagesLoaded, props.headings]);

  let activeHeading = null;
  const windowOffset = height / 2;
  const scrollTop = y + windowOffset;
  for (let i = offsets.length - 1; i >= 0; i--) {
    const { id, offset } = offsets[i];
    if (scrollTop >= offset) {
      activeHeading = id;
      break;
    }
  }

  const slugger = new Slugger();
  return (
    <StyledList>
      {props.headings.map(({ depth, value }) => {
        const text = striptags(value);
        const slug = slugger.slug(text);
        return (
          <StyledListItem
            key={slug}
            className={cn({ active: slug === activeHeading })}
            style={{ paddingLeft: depth !== 2 && 16 }}
          >
            <a href={`#${slug}`} onClick={handleHeadingClick}>
              {text}
            </a>
          </StyledListItem>
        );
      })}
    </StyledList>
  );
}

SectionNav.propTypes = {
  headings: PropTypes.array.isRequired,
  imagesLoaded: PropTypes.bool.isRequired,
  contentRef: PropTypes.object.isRequired
};