import React, { useEffect, useState } from 'react';
import styled from 'styled-components';

import v from '../../styles/Variables';

interface Props {
  /**
   * The icon or words that will show on the button, must be wrapped in valid JSX like a span
   */
  delimiter?: string;
  /**
   * Classes to be applied to the delimiter itself (wrapped in a span)
   */
  delimiterTheme?: string;
  /**
   * When done scrolling, where focus should  go for screen readers
   */
  focusEl?: string;
  /**
   * Position from the right
   */
  right: number;
  /**
   * The height and width of the button
   */
  size?: number;
  /**
   * An ID of where to scroll to, if excluded, will be the top of the page
   */
  target?: string | null;
  /**
   * Classes applied to the button wrapper
   */
  theme?: string;
  /**
   * How far the user has to scroll before the button shows, if excluded, it will always show
   */
  threshold?: number;
}

interface Style {
  size?: number;
  right?: number;
}

const ScrollToTop = ({ delimiter = '↑', delimiterTheme, focusEl = '#app', right = 40, size = 40, target, theme, threshold = 100 }: Props) => {
  const [show, showSetter] = useState(threshold ? false : true);

  useEffect(() => {
    if (window)
      window.addEventListener('scroll', () => {
        if (threshold && window.scrollY > threshold) {
          showSetter(true);
        } else {
          showSetter(false);
        }
      });
  }, [threshold]);

  const scrollToTop = () => {
    if (!target) {
      window.scrollTo({ top: 0, behavior: 'smooth' });
    } else {
      const elmnt = document.getElementById(target);
      if (elmnt) elmnt.scrollIntoView({ behavior: 'smooth' });
    }
  };

  return (
    <span data-test="component-scroll-to-top" id="nwc--back-to-top">
      {show === true && (
        <STT
          className={theme}
          onClick={() => {
            scrollToTop();
            const el = document.querySelector(focusEl) as HTMLElement;
            if (el !== null) el.focus();
          }}
          size={size}
          right={right}
          aria-label="Scroll back to top"
        >
          <span data-test="component-scroll-to-top-delimiter" className={delimiterTheme}>
            {delimiter}
          </span>
        </STT>
      )}
    </span>
  );
};

export default ScrollToTop;

/* styles */
const STT = styled.button<Style>`
  position: fixed;
  bottom: 25px;
  right: ${({ right }) => `${right}px`};
  height: ${({ size }) => `${size}px`};
  width: ${({ size }) => `${size}px`};
  line-height: ${({ size }) => `${size}px`};
  padding: 0;
  border: none;
  background: ${v.colors.dark222};
  color: ${v.colors.light};
  font-size: 14px;
`;
