import React from 'react'
import { connect } from 'react-redux'
import PostList from '../components/PostList'
import { fetchPosts, checkFreshness, clearCache } from '../actions'
import { debug } from '../util/logging'
import { connectedListProps, fetchWithCache, createCacheId } from '../util/caching'
import { isEqual, pick, differenceBy, union } from 'lodash'
import { find, get } from 'lodash/fp'
const { array, bool, func, number, object, string } = React.PropTypes

export const fetch = fetchWithCache(fetchPosts)

const findExpandedPostId = state => {
  const modal = find(m => m.type === 'expanded-post', state.openModals)
  return get('params.id', modal)
}

@connect((state, props) => ({
  ...connectedListProps(state, props, 'posts'),
  expandedPostId: findExpandedPostId(state),
  parentPost: props.parentPost
}), null, null, {withRef: true})
export class ConnectedPostList extends React.Component {
  static propTypes = {
    subject: string.isRequired,
    id: string.isRequired,
    posts: array,
    freshCount: number,
    dispatch: func,
    total: number,
    pending: bool,
    query: object,
    omit: string, // omit posts with this id from the query
    hide: array, // just hide posts with this id from the results
    hideMobileSearch: bool,
    expandedPostId: string,
    parentPost: object,
    noPostsMessage: string,
    module: object,
    showProjectActivity: bool
  }

  static contextTypes = {
    currentUser: object
  }

  loadMore = () => {
    let { posts, dispatch, total, pending, subject, id, query, omit } = this.props
    let offset = posts.length
    if (!pending && offset < total) {
      dispatch(fetch(subject, id, {...query, offset, omit}))
    }
  }

  checkForUpdates = currentPosts => {
    const { dispatch, subject, id, query, omit } = this.props

    const freshnessIds = p => {
      if (p.type === 'project-activity') {
        p = p.project
      }
      return pick(p, ['id', 'updated_at'])
    }

    this.visibility.visible() && dispatch(checkFreshness(
      subject,
      id,
      (currentPosts || this.props.posts).map(freshnessIds),
      {limit: 5, offset: 0, omit, ...query}
    ))

    // every time we check for updates, whether it's due to the timeout
    // elapsing, the contents of the list changing, or the user returning to the
    // browser tab, we want to reset the timeout so that we don't check too
    // frequently. this is why we use setTimeout repeatedly instead of
    // setInterval.
    this.scheduleCheckForUpdates()
  }

  scheduleCheckForUpdates (currentPosts) {
    if (this.scheduledCheck) clearTimeout(this.scheduledCheck)
    this.scheduledCheck = setTimeout(this.checkForUpdates, 60000)
  }

  componentDidMount () {
    this.scheduleCheckForUpdates(this.props.posts)
    this.visibility = require('visibility')()
    this.visibility.on('show', this.checkForUpdates)
  }

  componentWillReceiveProps (nextProps) {
    if (differenceBy(nextProps.posts, this.props.posts, 'id').length !== 0) {
      this.scheduleCheckForUpdates(nextProps.posts)
    }
  }

  componentWillUnmount () {
    clearTimeout(this.scheduledCheck)
    this.visibility.removeListener('show', this.checkForUpdates)
  }

  shouldComponentUpdate (nextProps) {
    return !isEqual(this.props, nextProps)
  }

  render () {
    const {
      dispatch, freshCount, posts, parentPost, total, pending, subject, id, query,
      hideMobileSearch, expandedPostId, noPostsMessage, module, showProjectActivity
    } = this.props

    const hide = union(this.props.hide, [expandedPostId])

    let refreshPostList
    if (freshCount !== 0) {
      refreshPostList = () => {
        dispatch(clearCache('postsByQuery', createCacheId(subject, id, query)))
        dispatch(fetch(subject, id, {...query}))
      }
    }

    const feedItems = posts

    if (module && feedItems.length > 0) {
      feedItems.splice(2, 0, module)
    }

    debug(`posts: ${posts ? posts.length : 0} / ${total || '??'}`)
    return <PostList
      posts={feedItems || []}
      loadMore={this.loadMore}
      {...{
        hide,
        hideMobileSearch,
        pending,
        refreshPostList,
        freshCount,
        noPostsMessage,
        parentPost,
        showProjectActivity
      }} />
  }
}

export default ConnectedPostList

@@ -3812,32 +3812,8 @@
 dule
- && feedItems.length %3E 0
 ) %7B%0A

fix test