import React from 'react';
import styled, { css } from 'styled-components';
import dayjs from 'dayjs';
import PropTypes from 'prop-types';
import {
  ChartStateLoading as Loading,
  ChartCard,
  ChartHeader,
  ChartTitle,
  ChartStateNoData,
  Helper
} from '@bufferapp/analyze-shared-components';
import AddReport from '@bufferapp/add-report';
import Summary from '../Summary';
import Story from '../Story';
import Dropdowns from '../Dropdowns';
import { Previous, Next } from '../Pagination/';
import Stories from '../../Stories';
import { LockIfNotAllowed, STORIES } from '@bufferapp/analyze-account';

const Breakdown = styled.section`
  padding: ${props => props.forReport ? '0 0 1.5rem' : '24px 16px'};
  overflow-x: ${props => props.forReport ? 'visible' : 'hidden'};
  white-space: nowrap;
`;

const Container = styled.div``;

const Content = styled.main`
  position: relative;
`;

const Pages = styled.div`
  transition: left .3s ease-out;
  left: 0%;
  position: relative;
  width: calc(${props => props.width}% + 12px);
  display: flex;
  align-items: stretch;

  ${props => props.page > 0 && css`
    left: calc(${props => props.page * -100}%);
  `}
`;

const Page = styled.div`
  flex: 1 100%;
  position: relative;
  display: flex;
  align-items: top;
  justify-content: flex-start;

`;

const getSortLabel = (attribute) => {
  const labels = {
    date: 'by date',
    reach: 'with most reach',
    completionRate: 'with highest completion rate',
  };
  return labels[attribute];
};

export const Title = ({ forReport, state }) =>
  <ChartTitle>
    {forReport ? `Stories ${getSortLabel(state.attributeToSortBy)}` : 'Stories insights' }
  </ChartTitle>;

class BreakdownContent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      page: 0,
    };
    this.previousPage = this.previousPage.bind(this);
    this.nextPage = this.nextPage.bind(this);
  }

  previousPage() {
    this.setState({
      page: this.state.page - 1,
    });
  }

  nextPage() {
    this.setState({
      page: this.state.page + 1,
    });
  }

  render() {
    const { metrics, forReport, selectedDay, attributeToSortBy, serviceId } = this.props;
    const { page } = this.state;

    // variables needed to build up the pages which contain stories and fillers
    // each page will be full with stories and the remainer are fillers
    let stories = Stories.filterAndSort(metrics, selectedDay, attributeToSortBy);
    stories = forReport ? stories.slice(0, 5) : stories;
    if (stories.length === 0) {
      return (
        <Container>
          <Content>
            <ChartStateNoData chartName="stories-breakdown" />
          </Content>
        </Container>
      );
    }
    const storiesTotal = stories.length;
    const maxPerPage = 5;
    const difference = storiesTotal % maxPerPage;
    const fillersTotal = (difference > 0) ? maxPerPage - difference : 0;
    const totalToRender = storiesTotal + fillersTotal;
    const pagesTotal = totalToRender / maxPerPage;
    const pagesTotalWidth = pagesTotal * 100; // 100 is 100% for full width
    const onLastPage = (pagesTotal - 1) === page || pagesTotal === 0;
    const onFirstPage = page === 0;

    // build up the stories elements to render, including any remaining fillers
    const storiesToRender = [];
    stories.forEach(story => storiesToRender.push(<Story {...story} serviceId={serviceId} />));
    for(let i=0; i<fillersTotal; i++) {
      storiesToRender.push(<Story filler />);
    }

    // build up the pages elements to render, ready to output
    const pagesToRender = [];
    for(let i=0; i<pagesTotal; i++) {
      let startOfSlice = i * maxPerPage;
      let endOfSlice = (i + 1) * maxPerPage;
      pagesToRender.push(<Page>{storiesToRender.slice(startOfSlice, endOfSlice)}</Page>);
    }

    return (
      <Container>
        <Content>
          {!onFirstPage && <Previous onClick={this.previousPage} />}
          <Breakdown forReport={forReport}>
            <Pages width={pagesTotalWidth} page={page}>
              {pagesToRender}
            </Pages>
          </Breakdown>
          {!onLastPage && <Next onClick={this.nextPage} />}
        </Content>
        <Summary forReport={forReport} stories={metrics} />
      </Container>
    );
  }
}

BreakdownContent.propTypes = {
  metrics: PropTypes.arrayOf(PropTypes.shape({
    thumbnail: PropTypes.string,
  })),
  loading: PropTypes.bool,
  forReport: PropTypes.bool,
};

BreakdownContent.defaultProps = {
  metrics: [],
  loading: false,
  forReport: false,
};

export { BreakdownContent };

class StoriesBreakdown extends React.Component {
  componentDidMount() {
    this.props.fetch();
  }

  render() {
    const { loading, stories } = this.props;

    let content = null;
    if (loading) {
      content = <Content><Loading noBorder large /></Content>;
    } else if (stories.length === 0) {
      content = <Content><ChartStateNoData chartName="stories-breakdown" /></Content>;
    } else {
      const dates = [...new Set(stories.map(story => dayjs.unix(story.date).startOf('day').valueOf()))];
      content = (
        <div>
          <Dropdowns
            sortBy={this.props.sortBy}
            filterBy={this.props.selectDay}
            attributeToSortBy={this.props.attributeToSortBy}
            selectedDay={this.props.selectedDay}
            dates={dates}
          />
          <BreakdownContent
            metrics={stories}
            attributeToSortBy={this.props.attributeToSortBy}
            selectedDay={this.props.selectedDay}
            serviceId={this.props.serviceId}
          />
        </div>
      );
    }

    return (
      <ChartCard>
        <LockIfNotAllowed {...{ STORIES }}>
          <ChartHeader>
            <Helper label='instagram disclaimer'>
              <Title />
            </Helper>
            <AddReport
              chart="stories-breakdown"
              state={{
                attributeToSortBy: this.props.attributeToSortBy,
                selectedDay: this.props.selectedDay,
              }}
            />
          </ChartHeader>
          {content}
        </LockIfNotAllowed>
      </ChartCard>
    );
  }
}

StoriesBreakdown.propTypes = {
  stories: PropTypes.arrayOf(PropTypes.shape({
    thumbnail: PropTypes.string,
  })),
  attributeToSortBy: PropTypes.string.isRequired,
  selectedDay: PropTypes.string.isRequired,
  loading: PropTypes.bool,
  sortBy: PropTypes.func.isRequired,
  selectDay: PropTypes.func.isRequired,
  fetch: PropTypes.func.isRequired,
};

StoriesBreakdown.defaultProps = {
  stories: [],
  loading: false,
  fetch: () => ({}),
};

export default StoriesBreakdown;
