import React from 'react'
import { compose } from 'redux'
import { connect } from 'react-redux'
import { defer, prefetch } from 'react-fetcher'
import {
  markActivityRead, markAllActivitiesRead, navigate, showModal, fetchActivity
} from '../actions'
import { get, map, isEmpty } from 'lodash/fp'
import cx from 'classnames'
import ScrollListener from '../components/ScrollListener'
import Avatar from '../components/Avatar'
import truncate from 'trunc-html'
import { humanDate } from '../util/text'
import { VIEWED_NOTIFICATIONS, trackEvent } from '../util/analytics'
import { getCurrentCommunity } from '../models/community'
const { array, bool, func, number, object } = React.PropTypes
import decode from 'ent/decode'
import {
  getActivitiesProps, actionText, bodyText, destination, activityAction
} from '../models/activity'
import { Modal, modalWrapperCSSId } from '../components/Modal'
import A from '../components/A'
import Dropdown from '../components/Dropdown'
import Icon from '../components/Icon'

const Notifications = compose(
  prefetch(({ dispatch, params: { id } }) => dispatch(fetchActivity(0, true, id))),
  connect(state => {
    const community = getCurrentCommunity(state)
    const slug = get('slug', community) || 'all'
    return getActivitiesProps(slug, state)
  }),
  defer(() => trackEvent(VIEWED_NOTIFICATIONS))
)((props, context) => {
  const { dispatch, total, pending, params } = props
  const offset = props.activities.length
  const loadMore = !pending && offset < total
    ? () => dispatch(fetchActivity(offset, false, params.id))
    : () => {}

  const activities = props.activities.map(activity =>
    activity.comment_id
      ? {...activity, comment: props.comments[activity.comment_id]}
      : activity)

  const markAllRead = () =>
    dispatch(markAllActivitiesRead(params.id, map('id', activities)))

  return <div>
    <div className='list-controls'>
      <button onClick={markAllRead}>
        Mark all as read
      </button>
    </div>
    <div className='activities'>
      {activities.map(activity =>
        <Activity key={activity.id} activity={activity} />)}
      <ScrollListener onBottom={loadMore} />
    </div>
  </div>
})

Notifications.propTypes = {
  activities: array,
  comments: object,
  pending: bool,
  dispatch: func,
  total: number
}

export default Notifications

const Activity = ({ activity }, { dispatch }) => {
  const {
    actor, action, post, comment, community, unread, created_at, meta: { reasons }
  } = activity
  const spacer = <span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>

  let text = bodyText(action, comment, post)

  let postName = !isEmpty(post) && post.type === 'welcome'
    ? `${post.relatedUsers[0].name}'s' welcoming post`
    : truncate(decode(post.name), 140).html

  let visit = () => {
    if (unread) dispatch(markActivityRead(activity.id))
    dispatch(navigate(destination(activity)))
  }

  return <div key={activity.id} className={cx('activity', {unread})}>
    <Avatar person={actor} />
    <div className='content'>
      <div className='title'>
        {actor.name}
        &nbsp;{actionText(action, comment, post, community, reasons)}&nbsp;
        {postName && <a onClick={visit}>{postName}</a>}
      </div>

      {text && <div className='body-text' dangerouslySetInnerHTML={{__html: text}} />}

      <div className='controls meta'>
        {humanDate(created_at)}
        {comment && <span>
          {spacer}
          <a onClick={visit}>Reply</a>
        </span>}
      </div>
    </div>
  </div>
}
Activity.contextTypes = {dispatch: func}

@connect((state, props) => getActivitiesProps('all', state))
export class NotificationsModal extends React.Component {
  static propTypes = {
    dispatch: func,
    activities: array,
    comments: object,
    total: number,
    pending: bool,
    onCancel: func
  }

  componentDidMount () {
    this.props.dispatch(fetchActivity(0, true))
  }

  render () {
    const { dispatch, activities, comments, total, pending, onCancel } = this.props
    const offset = activities.length
    const loadMore = !pending && offset < total
      ? () => dispatch(fetchActivity(offset, false))
      : () => {}

    const scrollListenerProps = {
      onBottom: loadMore,
      elementId: modalWrapperCSSId
    }

    const markAllRead = () =>
      dispatch(markAllActivitiesRead(null, map('id', activities)))

    return <Modal id='notifications-modal' onCancel={onCancel}
      title={<button onClick={markAllRead}>
        Mark all as read
      </button>}>
      <ul className='notifications-list' onClick={onCancel}>
        {activities.map(activity => <li key={activity.id}>
          <NotificationsDropdownItem activity={activity}
            comment={comments[activity.comment_id]} />
        </li>)}
      </ul>
      <ScrollListener {...scrollListenerProps} />
    </Modal>
  }
}

export const NotificationsDropdown = connect(
  (state, props) => getActivitiesProps('all', state)
)(props => {
  const { dispatch, newCount, activities, comments, pending } = props
  return <Dropdown alignRight rivalrous='nav' className='notifications-list'
    onOpen={() => dispatch(fetchActivity(0, true))}
    toggleChildren={<span>
      <Icon name='Bell' />
      {newCount > 0 && <div className='badge'>{newCount}</div>}
    </span>}>
    {pending && <li className='loading'>Loading...</li>}
    {activities.slice(0, 20).map(activity => <li key={activity.id}>
      <NotificationsDropdownItem activity={activity}
        comment={comments[activity.comment_id]} />
    </li>)}
    {!pending && <li className='bottom'>
      <a onClick={() => dispatch(showModal('notifications'))}>See all</a>
    </li>}
  </Dropdown>
})

const NotificationsDropdownItem = ({ activity, comment }, { dispatch }) => {
  const { id, actor, action, post, unread, community, meta: { reasons } } = activity
  const postName = !isEmpty(post) && truncate(decode(post.name), 140).html
  const markAsRead = () => unread && dispatch(markActivityRead(id))
  const onClick = () => {
    markAsRead()
    const extraAction = activityAction(activity)
    if (extraAction) dispatch(extraAction)
  }
  return <A to={destination(activity)} className={cx({unread})}
    onClick={onClick}>
    {unread && <div className='dot-badge' />}
    <Avatar person={actor} isLink={false} />
    <span>
      <strong>{actor.name}</strong>&nbsp;
      {actionText(action, comment, post, community, reasons)} {postName}
    </span>
  </A>
}
NotificationsDropdownItem.contextTypes = {dispatch: func}

@@ -146,16 +146,47 @@
 mport %7B%0A
+  closeModal,%0A  fetchActivity,%0A
   markAc
@@ -196,16 +196,18 @@
 ityRead,
+%0A 
  markAll
@@ -221,16 +221,18 @@
 iesRead,
+%0A 
  navigat
@@ -233,16 +233,18 @@
 avigate,
+%0A 
  showMod
@@ -249,23 +249,8 @@
 odal
-, fetchActivity
 %0A%7D f
@@ -855,17 +855,17 @@
 port
- %7B
  Modal,
+ %7B
  mod
@@ -3989,18 +3989,8 @@
 ding
-, onCancel
  %7D =
@@ -4403,28 +4403,8 @@
 dal'
- onCancel=%7BonCancel%7D
 %0A   
@@ -4537,24 +4537,44 @@
 nClick=%7B
-onCancel
+() =%3E dispatch(closeModal())
 %7D%3E%0A     

fix close button on notifications modal