import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import {
  ChartStateNoData as NoData,
  ChartStateLoading as Loading,
  ChartCard,
  ChartHeader,
  GridItem,
  Container,
  CHANNEL_TYPES,
} from '@bufferapp/analyze-shared-components';
import AddReport from '@bufferapp/add-report';
import GraphQLWrapper, { formatQueryVariables } from '@bufferapp/analyze-shared-components/GraphQLWrapper';
import Title from '../Title';
import QUERY, { dataParser } from '../../query';

const Grid = styled.ul`
  display: flex;
  flex-wrap: wrap;
  padding: 0;
  margin: 0 auto;
`;

const TableWithMetrics = ({ daily, totals }) =>
  (<Grid>
    {totals.map(metric => (<GridItem
      key={metric.label}
      metric={metric}
      dailyData={daily}
      gridWidth={`${100 / totals.length}%`}
      inline
      showPercentSign={metric.key === 'engagement_rate'}
    />))}
  </Grid>);

TableWithMetrics.defaultProps = {
  daily: [],
};

TableWithMetrics.propTypes = {
  daily: PropTypes.arrayOf(PropTypes.shape({
    day: PropTypes.string,
    metrics: PropTypes.arrayOf(PropTypes.shape({
      diff: PropTypes.number,
      label: PropTypes.string,
      value: PropTypes.number,
    })),
  })),
  totals: PropTypes.arrayOf(PropTypes.shape({
    label: PropTypes.string,
    value: PropTypes.number,
    diff: PropTypes.number,
  })).isRequired,
};

export const Table = (props) => {
  const variables = formatQueryVariables(props.profile, {
    startDate: props.startDate,
    endDate: props.endDate,
  });

  return (
    <React.Fragment>
      {props.daily && <TableWithMetrics {...props} />}
      {!props.daily && (
        <GraphQLWrapper
          {...props}
          graphQlProps={{
            dataParser,
            query: QUERY,
            variables,
            content: TableWithMetrics,
          }}
        />
      )}
    </React.Fragment>
  );
};

const Content = ({ metrics, loading, hasError }) => {
  let content = null;
  if (hasError) {
    content = null;
  } else if (loading) {
    content = <Loading active noBorder />;
  } else if (metrics.totals.length === 0) {
    content = <NoData chartName="averages" channelType={CHANNEL_TYPES.aggregates} />;
  } else {
    content = (
      <TableWithMetrics daily={metrics.daily} totals={metrics.totals} />
    );
  }

  return (
    <ChartCard hasError={hasError} >
      <ChartHeader>
        <Title />
        <AddReport chart="average" />
      </ChartHeader>
      <Container id="js-dom-to-png-average">
        {content}
      </Container>
    </ChartCard>
  );
};

Content.defaultProps = {
  loading: false,
  hasError: false,
  metrics: {
    daily: [],
    totals: [],
  },
};

Content.propTypes = {
  loading: PropTypes.bool,
  hasError: PropTypes.bool,
  metrics: PropTypes.shape({
    daily: PropTypes.arrayOf(PropTypes.shape({
      day: PropTypes.string,
      metrics: PropTypes.arrayOf(PropTypes.shape({
        diff: PropTypes.number,
        label: PropTypes.string,
        value: PropTypes.number,
      })),
    })),
    totals: PropTypes.arrayOf(PropTypes.shape({
      label: PropTypes.string,
      value: PropTypes.number,
      diff: PropTypes.number,
    })),
  }).isRequired,
};

function AverageTable (props) {
  const variables = formatQueryVariables(props.profile, {
    startDate: props.startDate,
    endDate: props.endDate,
  });

  return (
    <React.Fragment>
      {props.profile.service !== 'linkedin' && <Content {...props} />}
      {props.profile.service === 'linkedin' && (
        <GraphQLWrapper
          {...props}
          graphQlProps={{
            dataParser,
            query: QUERY,
            variables,
            content: Content,
            save: props.save,
            title: 'Average Performance',
          }}
        />
      )}
    </React.Fragment>
  );
}

export default AverageTable;

