import React, { useState } from 'react';
import PropTypes from 'prop-types';
import styled, { css } from 'styled-components';

import {
  ChartStateNoData as NoData,
  ChartStateLoading as Loading,
  ChartCard,
  ChartHeader,
} from '../index';
import Text from '@bufferapp/components/Text';

import PostItem from './components/PostItem';
import PostsHeader from './components/PostsHeader';
import PostsCountBar from './components/PostsHeader/components/PostsCountBar';
import BreakdownLegend from './components/BreakdownLegend';
import ContentModal from '../ContentModal';

import {
  geyser,
} from '@bufferapp/components/style/color';

const ChartContainer = styled.div`
  position: relative;
  border-radius: 2px;
  font-size: 12px;
  min-height: 177px;
  opacity: ${props => (props.searching ? '.3' : '1')};
  min-width: 1022px;
`;

const PostsTableWrapper = styled.ol`
  padding: 0;
  margin: 0;
  list-style: none;
  background: #FFFFFF;
  border: 1px solid ${geyser};
  border-width: 1px 0;

  ${props => props.forReport && css`
    background: transparent;
    border: 0 none;
    padding: 0 0 0.75rem;
    margin: 1rem 0 0;
  `}
`;

const GridContainer = styled.div`
  position: relative;
`;

const Footer = styled.footer`
  padding-top: 1rem;
  padding-bottom: 1rem;
  text-align: center;
`;

function formatPostForModal(post) {
  const formattedPost = {
    details: [{
      ...post,
    }],
  };

  return [formattedPost];
}

export const Table = (props) => {
  const { metrics, service, config } = props;
  const [postForModal, setPostForModal] = useState(null);

  return (
    <React.Fragment>
      {postForModal && <ContentModal
        posts={formatPostForModal(postForModal)}
        closeModal={() => { setPostForModal(null); }}
      />}
      <ChartContainer searching={props.searching}>
        {props.forReport && <BreakdownLegend
          posts={metrics.length}
          searchTerms={props.searchTerms}
          selectedMetric={props.selectedMetric}
          descending={props.isDescendingSelected}
        />}
        <PostsTableWrapper forReport={props.forReport} className="post-table-wrapper">
          {metrics.map((post, index) =>
            (<PostItem
              key={post.id}
              index={index}
              timezone={props.timezone}
              post={post}
              config={service ? config[service].postMetrics : config.postMetrics}
              exporting={props.exporting}
              forReport={props.forReport}
              onViewPost={setPostForModal}
            />),
          )}
        </PostsTableWrapper>
      </ChartContainer>
    </React.Fragment>
  );
};

Table.defaultProps = {
  forReport: false,
  searchTerms: [],
  config: null,
  service: null,
};

Table.propTypes = {
  config: PropTypes.shape(),
  forReport: PropTypes.bool,
  timezone: PropTypes.string.isRequired,
  service: PropTypes.string,
  metrics: PropTypes.arrayOf(PropTypes.shape({
    date: PropTypes.number,
    id: PropTypes.string,
    serviceLink: PropTypes.string,
    statistics: PropTypes.shape({
      comments: PropTypes.number,
      postClicks: PropTypes.number,
      postImpressions: PropTypes.number,
      postReach: PropTypes.number,
      reactions: PropTypes.number,
      shares: PropTypes.number,
    }),
    text: PropTypes.string,
    type: PropTypes.string,
  })).isRequired,
  exporting: PropTypes.bool.isRequired,
  searchTerms: PropTypes.arrayOf(PropTypes.string),
  isDescendingSelected: PropTypes.bool.isRequired,
  sortBy: PropTypes.string.isRequired,
};

const PostsTable = (props) => {
  const {
    activePostsCount,
    addToReportButton,
    config,
    exporting,
    handlePostsCountClick,
    isDescendingSelected,
    isDropdownOpen,
    loading,
    metrics,
    searchTerms,
    searching,
    selectMetric,
    selectedMetric,
    hide,
    service,
    timezone,
    title,
    toggleDropdown,
    forReport,
  } = props;

  if (hide === true) {
    return null;
  }

  let content = null;
  if ((loading && !searching) || (searching && metrics.length === 0)) {
    content = <Loading active noBorder large />;
  } else if (metrics.length === 0 && !loading) {
    if (searchTerms.length) {
      content = (<NoData chartName="posts-table" >
        <Text>There are no posts in this date range that match your terms</Text>
      </NoData>);
    } else content = <NoData />;
  } else {
    content = (
      <div>
        <Table
          config={config}
          searching={searching}
          metrics={metrics}
          timezone={timezone}
          service={service}
          exporting={exporting}
          forReport={forReport}
          sortBy={selectedMetric}
        />
        <Footer>
          <PostsCountBar
            handlePostsCountClick={handlePostsCountClick}
            activePostsCount={activePostsCount}
            postsCounts={props.postsCounts}
          />
        </Footer>
      </div>
    );
  }

  return (
    <ChartCard>
      <ChartHeader>
        {title}
        {addToReportButton}
      </ChartHeader>
      <GridContainer>
        {(metrics.length > 0 || searchTerms.length > 0) && <PostsHeader
          {...props}
          metrics={service ? config[service].sortMetrics : config.sortMetrics}
          selectedMetric={selectedMetric}
          isDescendingSelected={isDescendingSelected}
          selectMetric={selectMetric}
          toggleDropdown={toggleDropdown}
          isDropdownOpen={isDropdownOpen}
          handlePostsCountClick={handlePostsCountClick}
          activePostsCount={activePostsCount}
        />}
        {content}
      </GridContainer>
    </ChartCard>
  );
};

PostsTable.defaultProps = {
  config: null,
  isDropdownOpen: false,
  loading: false,
  searching: false,
  forReport: false,
  addToReportButton: null,
  hide: null,
  exporting: undefined,
  searchTerms: [],
  title: null,
  service: null,
};

PostsTable.propTypes = {
  config: PropTypes.arrayOf(),
  loading: PropTypes.bool,
  searching: PropTypes.bool,
  timezone: PropTypes.string.isRequired,
  title: PropTypes.node,
  service: PropTypes.string,
  forReport: PropTypes.bool,
  metrics: PropTypes.arrayOf(PropTypes.shape({
    date: PropTypes.number,
    id: PropTypes.string,
    serviceLink: PropTypes.string,
    statistics: PropTypes.shape({
      comments: PropTypes.number,
      postClicks: PropTypes.number,
      postImpressions: PropTypes.number,
      postReach: PropTypes.number,
      reactions: PropTypes.number,
      shares: PropTypes.number,
    }),
    text: PropTypes.string,
    type: PropTypes.string,
  })).isRequired,
  isDropdownOpen: PropTypes.bool,
  isDescendingSelected: PropTypes.bool.isRequired,
  selectedMetric: PropTypes.shape({
    key: PropTypes.string,
    label: PropTypes.string,
  }).isRequired,
  toggleDropdown: PropTypes.func.isRequired,
  selectMetric: PropTypes.func.isRequired,
  handlePostsCountClick: PropTypes.func.isRequired,
  activePostsCount: PropTypes.number.isRequired,
  addToReportButton: PropTypes.element,
  hide: PropTypes.string,
  exporting: PropTypes.bool,
  searchTerms: PropTypes.arrayOf(PropTypes.string),
};

export default PostsTable;
