// @flow
import React, {
  useState,
  useEffect,
  useLayoutEffect,
  useRef,
  useMemo,
  useCallback,
} from 'react';
import styled from 'styled-components';
import { type AnimatedFilterBarProps } from './animated-filter-bar.proptypes';
import { FilterTab } from './components/filter-tab';
import { SelectionIndicator } from './components/selection-indicator';
import { Box } from '../../primitives';

const Container = styled(Box)`
  position: relative;
`;

function getButtonLabels(options) {
  const buttonLabels = {};
  for (let i = 0; i < options.length; i++) {
    buttonLabels[options[i].value] = options[i].label;
  }
  return buttonLabels;
}

export const AnimatedFilterBar = ({
  options,
  value,
  spacing,
  fontSize = 'f1',
  onChange,
}: AnimatedFilterBarProps) => {
  // Initialize map of labels
  const buttonLabels = useMemo(() => getButtonLabels(options), [options]);

  // Create a ref only to the button for the selected value (if there is one).
  const selectedSwitcherTabRef = useRef<?HTMLButtonElement>(null);

  // Visual states
  const [showSelector, setShowSelector] = useState(false);
  const [selectorOffset, setSelectorOffset] = useState({ x: 0, y: 0 });

  const setSelectorLocation = useCallback(() => {
    const target = selectedSwitcherTabRef.current;

    if (target == null) {
      return;
    }

    setSelectorOffset({
      x: target.offsetLeft,
      y: target.offsetTop,
    });

    setShowSelector(true);
  }, []);

  // set selector location when value changes
  useLayoutEffect(() => setSelectorLocation(), [value, setSelectorLocation]);

  // handle resize events
  useEffect(() => {
    window.addEventListener('resize', setSelectorLocation);
    return () => window.removeEventListener('resize', setSelectorLocation);
  }, [setSelectorLocation]);

  return (
    <Container
      stacked="row"
      align="center"
      justify="space-between"
      spacing={spacing !== undefined ? spacing : ['pv2', 'ph3']}
    >
      {options.map((option) => {
        return (
          <FilterTab
            key={option.value}
            forwardRef={option.value === value ? selectedSwitcherTabRef : null}
            value={option.value}
            selected={option.value === value}
            onClick={onChange}
            label={option.label}
            fontSize={fontSize}
          />
        );
      })}
      {showSelector && value != null && (
        <SelectionIndicator selectorOffset={selectorOffset} fontSize={fontSize}>
          {buttonLabels[value]}
        </SelectionIndicator>
      )}
    </Container>
  );
};

AnimatedFilterBar.displayName = 'AnimatedFilterBar';
