import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import AddReport from '@bufferapp/add-report';
import { PostsTable } from '@bufferapp/analyze-shared-components';
import { Table } from '@bufferapp/analyze-shared-components/PostsTable';
import Title from './components/Title';
import GraphQLWrapper, {
  formatQueryVariables,
} from '@bufferapp/analyze-shared-components/GraphQLWrapper';
import QUERY, { dataParser } from './query';

import { metricsConfig } from './metricsConfig';
import { actions } from './reducer';

const Content = (props) => {
  if (props.profile.service == 'linkedin') {
    props = {
      ...props,
      metrics: injectProfileInPosts(props.metrics, props.profile),
    };
  }

  return (
    <div id="js-dom-to-png-posts">
      <PostsTable
        {...props}
        postsCounts={[
          { value: '5' },
          { value: '10' },
          { value: '25' },
          { value: '50' },
          { value: 'All' },
        ]}
        addToReportButton={
          <AddReport
            chart="posts"
            state={{
              descending: props.isDescendingSelected,
              sortBy: props.selectedMetric?.apiKey,
              selectedMetric: props.selectedMetric,
              limit: props.activePostsCount,
              searchTerms: props.searchTerms,
            }}
          />
        }
      />
    </div>
  );
};

export class PostsTableWrapper extends React.Component {
  componentDidMount() {
    if (this.props.profileService !== 'linkedin') {
      this.props.fetch();
    }
  }

  render() {
    return <Content {...this.props} />;
  }
}

PostsTableWrapper.defaultProps = {
  loading: false,
};

PostsTableWrapper.propTypes = {
  config: PropTypes.arrayOf().isRequired,
  isDescendingSelected: PropTypes.bool.isRequired,
  selectedMetric: PropTypes.shape({
    key: PropTypes.string,
    apiKey: PropTypes.string,
    label: PropTypes.string,
  }).isRequired,
  activePostsCount: PropTypes.number.isRequired,
  searchTerms: PropTypes.arrayOf(PropTypes.string).isRequired,
};

function getService(state) {
  return state.profiles.selectedProfile
    ? state.profiles.selectedProfile.service
    : '';
}

function injectProfileInPosts(posts, profile) {
  return posts.map(post => ({
    ...post,
    profile,
  }));
}

// default export = container
export const ReduxComponent = connect(
  state => ({
    loading: state.posts.loading,
    timezone: state.profiles.selectedProfile
      ? state.profiles.selectedProfile.timezone
      : '',
    metrics: injectProfileInPosts(
      state.posts.posts,
      state.profiles.selectedProfile,
    ),
    hide: !state.profiles.selectedProfile,
  }),
  dispatch => ({
    fetch: () => dispatch(actions.fetch()),
  }),
)(PostsTableWrapper);

function TableWithConfig(props) {
  const variables = formatQueryVariables(props.profile, {
    startDate: props.startDate,
    endDate: props.endDate,
    orderBy: {
      field: props.selectedMetric.key.toUpperCase(),
      order: props.isDescendingSelected ? 'DESC' : 'ASC',
    },
    searchTerms: props.searchTerms,
    limit: props.activePostsCount ? props.activePostsCount : 1000,
  });

  props = {
    ...props,
    config: metricsConfig,
  };

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

export default connect(
  state => ({
    startDate: state.date.startDate,
    endDate: state.date.endDate,
    profile: state.profiles.selectedProfile,
    selectedMetric: state.posts.selectedMetric,
    config: metricsConfig,
    service: getService(state),
    searchTerms: state.posts.searchTerms,
    isDescendingSelected: state.posts.isDescendingSelected,
    title: <Title service={getService(state)} />,
    searching: state.posts.searching,
    activePostsCount: state.posts.activePostsCount,
  }),
  dispatch => ({
    save: result => dispatch(actions.save(result)),
    selectMetric: ({ metric, descending }) =>
      dispatch(actions.selectMetric(metric, descending)),
    search: tags => dispatch(actions.search(tags)),
    handlePostsCountClick: ({ postsCount }) =>
      dispatch(actions.handlePostsCountClick(postsCount)),
    handlePostsSortClick: ({ isDescendingSelected }) =>
      dispatch(actions.handlePostsSortClick(isDescendingSelected)),
  }),
)((props) => {
  const variables = formatQueryVariables(props.profile, {
    startDate: props.startDate,
    endDate: props.endDate,
    orderBy: {
      field: props.selectedMetric.key.toUpperCase(),
      order: props.isDescendingSelected ? 'DESC' : 'ASC',
    },
    searchTerms: props.searchTerms,
    limit: props.activePostsCount ? props.activePostsCount : 1000,
  });
  return (
    <React.Fragment>
      {props.profile && (
        <React.Fragment>
          {props.profile.service === 'linkedin' && (
            <GraphQLWrapper
              {...props}
              timezone={props.profile.timezone}
              graphQlProps={{
                dataParser,
                query: QUERY,
                variables,
                content: Content,
                title: 'Posts Insights',
                save: data => props.save(data),
              }}
            />
          )}
          {props.profile.service !== 'linkedin' && (
            <ReduxComponent {...props} />
          )}
        </React.Fragment>
      )}
    </React.Fragment>
  );
});

// export reducer, actions and action types
export reducer, { actions, actionTypes } from './reducer';
export middleware from './middleware';
export { TableWithConfig as Table };
export Title from './components/Title';
