import React, { useCallback } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import Button from 'Components/buttons/button';
import Selector from 'Components/selector/selector';
import { screenSize } from 'Themes/utils/mediaQueries';
import { ACTIONS_WIDTH_PERCENT } from '../constants';

const MAX_ACTION_BUTTONS = 4;

const ActionsItem = styled.div`
  @media ${screenSize('desktop')} {
    display: inline-flex;
    justify-content: flex-end;
    flex-basis: ${ACTIONS_WIDTH_PERCENT}%;
    margin: 0 16px 0 0;
  }
`;

const Actions = styled.div`
  margin: 16px auto;
  display: flex;
  flex-direction: column;
  justify-content: ${({ length }) =>
    length < MAX_ACTION_BUTTONS ? 'center' : 'start'};
  align-items: center;

  @media ${screenSize('desktop')} {
    margin: 16px 0;
    align-items: flex-end;
  }
`;

const getActionValue = action => action.label.split(' ').join('-');

const actionToOption = action => ({
  value: getActionValue(action),
  label: action.label,
});

const actionButtonMargin = (actions, i) =>
  i === actions.length - 1 ? '0' : '8px';

const useActionButton = actions =>
  useCallback(
    (action, i) => (
      <Button
        key={`action-${getActionValue(action)}`}
        marginBottom={actionButtonMargin(actions, i)}
        small
        primary={i === 0}
        onClick={action.onClick}
      >
        {action.label}
      </Button>
    ),
    [actions],
  );

const useOnLastActionButtonChange = actions =>
  useCallback(
    option => {
      const clickedAction = actions.find(
        action => action.label === option.label,
      );

      clickedAction.onClick();
    },
    [actions],
  );

const useLastActionButton = (ActionButton, actions) =>
  useCallback(
    lastActions => {
      if (lastActions.length === 1) {
        return (
          <ActionButton
            key={`action-${getActionValue(lastActions[0])}`}
            {...lastActions[0]}
          />
        );
      } else if (lastActions.length > 1) {
        const onLastActionButtonChange = useOnLastActionButtonChange(actions);
        return (
          <Selector
            key="more-options"
            small
            placeholder="More Options"
            options={lastActions.map(actionToOption)}
            onChange={onLastActionButtonChange}
          />
        );
      }

      return [];
    },
    [ActionButton, actions],
  );

const getFirstActionButtons = (actions, ButtonComponent) =>
  actions.slice(0, MAX_ACTION_BUTTONS - 1).map(ButtonComponent);

const getLastActionButton = (actions, ButtonComponent) =>
  ButtonComponent(actions.slice(MAX_ACTION_BUTTONS - 1));

const CardActions = ({ actions }) => {
  const ActionButton = useActionButton(actions);
  const LastActionButton = useLastActionButton(ActionButton, actions);

  const actionButtons = [
    ...getFirstActionButtons(actions, ActionButton),
    getLastActionButton(actions, LastActionButton),
  ];

  return (
    <ActionsItem>
      <Actions length={actions.length}>{actionButtons}</Actions>
    </ActionsItem>
  );
};

CardActions.propTypes = {
  actions: PropTypes.arrayOf(
    PropTypes.shape({
      label: PropTypes.string.isRequired,
      onClick: PropTypes.func.isRequired,
    }).isRequired,
  ).isRequired,
};

CardActions.displayName = 'CardActions';

export default CardActions;
