import React, { useContext, useMemo } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import Status from 'Components/status/status';
import CardTableContext from 'Components/cardTable/cardTableContext';
import childrenToArray from 'Components/utils/childrenToArray';
import statusTypes from 'Components/utils/types/statusTypes';
import { whiteColor } from 'Themes/utils/colorPickers';
import { screenSize } from 'Themes/utils/mediaQueries';
import CardItem from '../cardItems/cardItem';
import { CARD_HEIGHT, CARD_V_PADDING, ITEMS_WIDTH_PERCENT } from '../constants';
import CardActions from './cardActions';

const StyledCard = styled.div`
  position: relative;
  min-height: ${CARD_HEIGHT - 2 * CARD_V_PADDING}px;
  background-color: ${whiteColor};
  border-radius: 4px;
  box-shadow: 0 6px 16px 0 rgba(0, 15, 25, 0.05),
    inset 0 -2px 2px 0 rgba(70, 77, 96, 0.05),
    inset 0 -1px 0 0 rgba(70, 77, 96, 0.1);
  margin: 8px;
  padding: ${CARD_V_PADDING * 2}px 0px ${CARD_V_PADDING}px;
  display: flex;
  flex-direction: column;
  justify-content: start;

  @media ${screenSize('desktop')} {
    padding: ${CARD_V_PADDING}px 8px;
    flex-direction: row;
  }
`;

const CardStatus = styled(Status)`
  position: absolute;
  top: 16px;
  left: 16px;

  @media ${screenSize('desktop')} {
    top: initial;
    bottom: 16px;
    left: 24px;
  }
`;

const CardItems = styled.div`
  display: flex;
  flex-direction: column;
  flex-basis: ${ITEMS_WIDTH_PERCENT}%;

  @media ${screenSize('desktop')} {
    padding: ${CARD_V_PADDING}px 8px;
    flex-direction: row;
  }
`;

const EmptyChild = ({ type }) => <CardItem type={type} />;

const renderChildren = (children, types) =>
  types.map(type => {
    const ChildWithType = childrenToArray(children).find(
      child => child.props.type === type,
    );

    if (ChildWithType) {
      return ChildWithType;
    }

    return <EmptyChild key={`item-${type}`} type={type} />;
  });

const bindCardActions = (actions, props) =>
  actions.map(({ label, onClick }) => ({
    label,
    onClick: () => onClick(props),
  }));

const Card = ({ children, actions, ...props }) => {
  const { status } = props;
  const { sections } = useContext(CardTableContext);
  const types = useMemo(() => sections.map(section => section.type), [
    sections,
  ]);

  return (
    <StyledCard {...props}>
      <CardItems>{renderChildren(children, types)}</CardItems>
      {actions && <CardActions actions={bindCardActions(actions, props)} />}
      {status && <CardStatus type={status.type}>{status.label}</CardStatus>}
    </StyledCard>
  );
};

Card.propTypes = {
  actions: PropTypes.arrayOf(
    PropTypes.shape({
      label: PropTypes.string.isRequired,
      onClick: PropTypes.func.isRequired,
    }).isRequired,
  ),
  status: PropTypes.shape({
    type: PropTypes.oneOf(statusTypes).isRequired,
    label: PropTypes.string.isRequired,
  }),
};

Card.displayName = 'Card';

export default Card;
