import React, { memo, useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { Helmet } from 'react-helmet';
import { defineMessages } from 'react-intl';
import { connect } from 'react-redux';
import InfiniteScroll from 'react-infinite-scroller';
import { compose, bindActionCreators } from 'redux';
import { createSelector, createStructuredSelector } from 'reselect';
import ListGroup from 'react-bootstrap/ListGroup';
import { FaComments } from 'react-icons/fa';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import styled from 'styled-components';
import Container from 'react-bootstrap/Container';
import { B as Breadcrumb } from './index-f3799490.js';
import { A as API_PREFIX, u as useInjectReducer, H as H2 } from './index-9c274173.js';
import { r as request, u as useInjectSaga } from './request-a3c74421.js';
import produce from 'immer';
import { t as topicsListReducer, a as topicsData, m as makeSelectTopic, l as loadTopicsActionsCreator } from './saga-f1165c7a.js';
import { takeLatest, call, put } from 'redux-saga/effects';
import { h as history } from './TopicsListComponent-fa574397.js';
import 'react-bootstrap/Breadcrumb';
import 'hoist-non-react-statics';
import 'invariant';
import 'lodash';
import 'sanitize.css/sanitize.css';
import 'react-router-dom';
import 'connected-react-router';
import 'redux-saga';
import 'history';

const CounterText = styled.div.withConfig({
  displayName: "ThreadListItem__CounterText",
  componentId: "sc-1dq38fj-0"
})(["font-size:0.7rem;"]);

function ThreadListItem(props) {
  return /*#__PURE__*/React.createElement(ListGroup.Item, {
    action: true,
    onClick: props.onClick
  }, /*#__PURE__*/React.createElement(Container, null, /*#__PURE__*/React.createElement(Row, null, /*#__PURE__*/React.createElement(Col, {
    md: 1
  }, /*#__PURE__*/React.createElement(FaComments, {
    size: 32
  })), /*#__PURE__*/React.createElement(Col, {
    md: 10
  }, /*#__PURE__*/React.createElement("h4", null, props.item.title), props.item.description), /*#__PURE__*/React.createElement(Col, {
    md: 1
  }, /*#__PURE__*/React.createElement(CounterText, null, props.item.posts_counter), /*#__PURE__*/React.createElement(CounterText, null, "Comments")))));
}

ThreadListItem.propTypes = {
  item: PropTypes.any,
  onClick: PropTypes.func
};

/*
 * AppConstants
 * Each action has a corresponding type, which the reducer knows and picks up on.
 * To avoid weird typos between the reducer and the actions, we save them as
 * constants here. We prefix them with 'yourproject/YourComponent' so we avoid
 * reducers accidentally picking up actions they shouldn't.
 *
 * Follow this format:
 * export const YOUR_ACTION_CONSTANT = 'yourproject/YourContainer/YOUR_ACTION_CONSTANT';
 */
const LOAD_THREADS = 'reactCommentsDjango/ThreadsList/LOAD_THREADS';
const LOAD_THREADS_SUCCESS = 'reactCommentsDjango/ThreadsList/LOAD_THREADS_SUCCESS';
const LOAD_THREADS_ERROR = 'reactCommentsDjango/ThreadsList/LOAD_THREADS_ERROR';

/*
 * ThreadListReducer
 *
 * The reducer takes care of our data. Using actions, we can
 * update our application state. To add a new action,
 * add it to the switch statement in the reducer function
 *
 */

const initialState = {
  threadsList: false
};
/* eslint-disable default-case, no-param-reassign */

const threadsListReducer = (state = initialState, action) => produce(state, draft => {
  switch (action.type) {
    case LOAD_THREADS:
      draft.loading = true;
      draft.error = false;
      draft.threadsList = false;
      break;

    case LOAD_THREADS_SUCCESS:
      draft.threadsList = action.threadsList;
      draft.loading = false;
      break;

    case LOAD_THREADS_ERROR:
      draft.error = action.error;
      draft.loading = false;
      break;
  }
});

/**
 * threads list selectors
 */

const selectThreads = state => state.threads || initialState;

const makeSelectThreadsList = () => createSelector(selectThreads, threadListState => threadListState.threadsList);

const Section = styled.section.withConfig({
  displayName: "Section",
  componentId: "sc-13xou8i-0"
})(["margin:3em auto;&:first-child{margin-top:0;}"]);

const CenteredSection = styled(Section).withConfig({
  displayName: "CenteredSection",
  componentId: "sc-1yf9vry-0"
})(["text-align:center;"]);

/*
 * HomePage Messages
 *
 * This contains all the text for the HomePage component.
 */
const scope = 'boilerplate.containers.HomePage';
defineMessages({
  threadsList: {
    id: `${scope}.threads`,
    defaultMessage: 'Threads'
  }
});

/*
 * App Actions
 *
 * Actions change things in your application
 * Since this boilerplate uses a uni-directional data flow, specifically redux,
 * we have these actions which are the only way your application interacts with
 * your application state. This guarantees that your state is up to date and nobody
 * messes it up weirdly somewhere.
 *
 * To add a new Action:
 * 1) Import your constant
 * 2) Add a function like this:
 *    export function yourAction(var) {
 *        return { type: YOUR_ACTION_CONSTANT, var: var }
 *    }
 */
/**
 * Load the threads List, this action starts the request saga
 *
 * @return {object} An action object with a type of LOAD_THREADS
 */

function loadThreads(topicSlug, nextHref) {
  return {
    type: LOAD_THREADS,
    topicSlug,
    nextHref
  };
}
/**
 * Dispatched when the threads List are loaded by the request saga
 *
 * @param  {array} threadsList The threads List data
 *
 * @return {object}      An action object with a type of LOAD_THREADS_SUCCESS passing the threadsList
 */

function threadsListLoaded(threadsList) {
  return {
    type: LOAD_THREADS_SUCCESS,
    threadsList
  };
}
/**
 * Dispatched when loading the threadsListitories fails
 *
 * @param  {object} error The error
 *
 * @return {object}       An action object with a type of LOAD_THREADS_ERROR passing the error
 */

function threadsListLoadingError(error) {
  return {
    type: LOAD_THREADS_ERROR,
    error
  };
}

var threadsActionsCreator = /*#__PURE__*/Object.freeze({
  __proto__: null,
  loadThreads: loadThreads,
  threadsListLoaded: threadsListLoaded,
  threadsListLoadingError: threadsListLoadingError
});

function getThreads(topicSlug, nextHref) {
  let url;

  if (nextHref) {
    url = nextHref;
  } else {
    url = `${API_PREFIX}threads/?topic__slug=${topicSlug}`;
  }

  return request(url, {
    method: 'GET',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
      'X-Requested-With': 'XMLHttpRequest'
    }
  });
}

const Api = {
  getThreads
};

function* getThreadsList(sagaArgs) {
  const {
    nextHref,
    topicSlug
  } = sagaArgs; // const username = yield select(makeSelectUsername())

  try {
    // Call our request helper (see '../../utils/request')
    // const repos = yield call(request, requestURL)
    const threadsList = yield call(Api.getThreads, topicSlug, nextHref);
    yield put(threadsListLoaded(threadsList));
  } catch (err) {
    yield put(threadsListLoadingError(err));
  }
} // export function* clearThreadsList() {}

/**
 * Root saga manages watcher lifecycle
 */

function* threadsData() {
  // Watches for LOAD_REPOS actions and calls getThreadsList when one comes in.
  // By using `takeLatest` only the result of the latest API call is applied.
  // It returns task descriptor (just like fork) so we can continue execution
  // It will be cancelled automatically on component unmount
  yield takeLatest(LOAD_THREADS, getThreadsList);
}

/*
 * ThreadsPage
 *
 * This is the first thing users see of our App, at the '/' route
 */
const threadsKey = 'threads';
const topicsKey = 'topics';
function ThreadsList({
  threadsActions,
  topicsActions,
  match,
  threadsList,
  topic,
  history: _history
}) {
  useInjectReducer({
    key: threadsKey,
    reducer: threadsListReducer
  });
  useInjectSaga({
    key: threadsKey,
    saga: threadsData
  });
  useInjectReducer({
    key: topicsKey,
    reducer: topicsListReducer
  });
  useInjectSaga({
    key: topicsKey,
    saga: topicsData
  });
  const [threads, setThreads] = useState([]);
  const [hasMoreItems, setHasMoreItems] = useState(false);
  const [nextHref, setNextHref] = useState(null);
  const breadcrumbSections = [{
    key: 'Topics',
    content: 'Topics',
    href: '/topics',
    // link: true,
    onClick: evt => {
      evt.preventDefault();
      history.push('/topics');

      if (_history) {
        // parent app history
        _history.push({
          pathname: `/topics`
        });
      }
    }
  }];
  useEffect(() => {
    topicsActions.loadTopic(match.params.topicSlug); // load threads from server

    threadsActions.loadThreads(match.params.topicSlug);
    return () => {
      // clear threads list while unmount
      threadsActions.threadsListLoaded(false);
    };
  }, []);

  const loadNextPage = () => {
    if (hasMoreItems) {
      // if we call next page setHasMore item false and waiting for a server response
      setHasMoreItems(Boolean(false));
      threadsActions.loadThreads(null, nextHref);
    }
  };

  const onThreadClick = (e, item) => {
    history.push(`/${topic.slug}/${item.id}/${item.slug}`);

    if (_history) {
      // parent app history
      _history.push({
        pathname: `/${topic.slug}/${item.id}/${item.slug}`
      });
    }
  };

  useEffect(() => {
    if (threadsList) {
      setThreads([...threads, ...threadsList.results]);
      setHasMoreItems(Boolean(threadsList.next));
      setNextHref(threadsList.next);
    }
  }, [threadsList]);
  let items = [];

  if (threads) {
    items = threads.map(item => /*#__PURE__*/React.createElement(ThreadListItem, {
      onClick: e => {
        onThreadClick(e, item);
      },
      key: item.id,
      item: item
    }));
  }

  return /*#__PURE__*/React.createElement("article", null, /*#__PURE__*/React.createElement(Helmet, null, /*#__PURE__*/React.createElement("title", null, "Threads List"), /*#__PURE__*/React.createElement("meta", {
    name: "description",
    content: "React comments Django threads List"
  })), /*#__PURE__*/React.createElement(Breadcrumb, {
    sections: breadcrumbSections
  }), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(CenteredSection, null, /*#__PURE__*/React.createElement(H2, null, topic && topic.title)), /*#__PURE__*/React.createElement(Section, null, /*#__PURE__*/React.createElement(InfiniteScroll, {
    pageStart: 0,
    loadMore: loadNextPage,
    hasMore: hasMoreItems // loader={<div key={this.state.nextHref} style={{clear: 'both'}} />} // fix https://github.com/CassetteRocks/react-infinite-scroller/issues/14#issuecomment-225835845

  }, /*#__PURE__*/React.createElement(ListGroup, null, items), threadsList && threadsList.count === 0 && /*#__PURE__*/React.createElement("h4", null, "There are no threads to show")))));
}
ThreadsList.propTypes = {
  threadsActions: PropTypes.shape({
    loadThreads: PropTypes.func.isRequired,
    threadsListLoaded: PropTypes.func.isRequired
  }).isRequired,
  topicsActions: PropTypes.shape({
    loadTopic: PropTypes.func.isRequired
  }).isRequired,
  match: PropTypes.object,
  threadsList: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
  topic: PropTypes.oneOfType([PropTypes.object, PropTypes.bool])
};
const mapStateToProps = createStructuredSelector({
  threadsList: makeSelectThreadsList(),
  topic: makeSelectTopic() // username: makeSelectUsername(),
  // loading: makeSelectLoading(),
  // error: makeSelectError(),

});
function mapDispatchToProps(dispatch) {
  return {
    threadsActions: bindActionCreators(threadsActionsCreator, dispatch),
    topicsActions: bindActionCreators(loadTopicsActionsCreator, dispatch)
  };
}
const withConnect = connect(mapStateToProps, mapDispatchToProps);
var index = compose(withConnect, memo)(ThreadsList);

export default index;
export { ThreadsList, mapDispatchToProps };
//# sourceMappingURL=index-c20e519e.js.map
