/**
 * ThreadDetail view
 *
 * Generated by coz on 2016-12-11,
 * from a template provided by apeman-asset-templates.
 *
 * @function ThreadDetailView
 */
'use strict'

import React, { Component, PropTypes as types } from 'react'
import defineDebug from 'debug'
import {
  ApView, ApViewHeader, ApViewBody,
  ApButton, ApContainer
} from 'apeman-react-basic'
import {
  asConnected,
  asLocaled,
  asView,
  asServed,
  forSpin,
  forTitle,
  forOne,
  forOgp,
  forTwitter,
  forCanonical,
  forEvent,
  forAuth,
  ofThread,
  forRecommend,
  combine
} from '../../wrappers'
import ThreadPostsView from '../thread/thread_posts_view'

import { IconClasses, ViewEvents } from 'ore-fol-enums'
import {
  ThreadPanel,
  ThreadDetailStyle,
  ThreadCardCollection
} from '../../fragments'
const { THREAD_UPDATE_EVENT, THREAD_DESTROY_EVENT } = ViewEvents
const { THREAD_ICON } = IconClasses

const debug = defineDebug('project:view:thread-detail')

const tagValues = (tags) => Object.keys(tags || {})
  .sort((v1, v2) => tags[ v2 ] - tags[ v1 ])

/** @lends ThreadDetailView */
class ThreadDetailView extends Component {
  // --------------------
  // Specs
  // --------------------
  static get propTypes () {
    return {}
  }

  static get defaultProps () {
    return {}
  }

  render () {
    const s = this
    const {
      props,
      l
    } = s
    let {
      thread,
      recommendedThreads
    } = props
    let ownThread = thread && s.isOwnThread(thread)
    let hasRecommendedThreads = recommendedThreads && (recommendedThreads.length > 0)
    return (
      <ApView id='thread-detail-view'
              wide
              className='view'
              spinning={ props.spinning }
              way={ props.way }
      >
        <ApViewHeader onLeftTap={ s.handlePop }
                      leftText={ null }
                      leftIcon={ props.popIcon }
                      titleText={ thread && thread.name }
                      titleIcon={ THREAD_ICON }
                      onRightTap={ null }
                      rightIcon={ null }
                      rightText={ null }
        />

        <ApViewBody style={ { paddingLeft: 0, paddingRight: 0 } }>
          {
            thread ? (
                <div className='thread-detail'
                     id={ `thread-detail-${thread.id}` }
                >
                  <ThreadDetailStyle prefix={ `#thread-detail-${thread.id}` }
                                     color={ thread.color }
                  />
                  <div className="thread-detail-header">
                    <ApContainer>
                      <ThreadPanel thread={ thread }
                                   tagValues={ tagValues(thread.tags) }
                                   editable={ ownThread }
                                   destroyable={ ownThread }
                                   lockable={ ownThread }
                                   onEdit={ s.handleEdit }
                                   onDestroy={ s.handleDestroy }
                                   onLock={ s.handleLock }
                                   onTag={ s.handleTag }
                                   sharable
                                   url={ s.detailUrl }
                      />
                    </ApContainer>
                  </div>
                  <div className="thread-detail-body">
                    <ApContainer>
                      <div className="embed-view-container">
                        <ThreadPostsView { ...props } />
                      </div>
                      <div>
                      </div>
                    </ApContainer>
                    {
                      hasRecommendedThreads ? (
                          <ApContainer>
                            <ThreadCardCollection heading={ l('headings.RECOMMENDED') }
                                                  threads={ recommendedThreads }
                                                  className='thread-recommend-list'
                            />
                          </ApContainer>
                        ) : null
                    }
                  </div>
                  <div className="thread-detail-footer">
                    <ApContainer>
                      {
                        thread.locked ? (
                            <p className="thread-detail-footer-message">{ l('messages.CANNOT_POST_BECAUSE_LOCKED') }</p>
                          ) : (
                            <ApButton onTap={ s.handlePost }>
                              { l('buttons.SHOW_NEW_POST') }
                            </ApButton>
                          )
                      }
                    </ApContainer>
                  </div>
                </div>
              ) : null
          }
        </ApViewBody>
      </ApView>
    )
  }

  // --------------------
  // Lifecycle
  // --------------------

  componentWillMount () {
    debug('willMount')
    const s = this

  }

  componentDidMount () {
    debug('didMount')
    const s = this

    const isThisThread = (thread) => Number(thread.id) === Number(s.props.threadId)
    s.listenEvent(THREAD_UPDATE_EVENT, ({ updated }) => {
      if (isThisThread(updated)) {
        s.reloadThread()
      }
    })
    s.listenEvent(THREAD_DESTROY_EVENT, ({ destroyed }) => {
      if (isThisThread(destroyed)) {
        s.handlePop()
      }
    })
  }

  componentWillUnmount () {
    debug('willUnmount')
    const s = this
  }

  // --------------------
  // Callbacks
  // --------------------

  threadDidLoad (thread) {
    const s = this
    const { urlForThread } = s.service('urlService')
    const { pageTitle } = s.service('localeService')
    const {
      reloadPostShareButtons,
      twitterMetaForThread,
      ogpMetaForThread
    } = s.service('shareService')

    s.titleForStack(pageTitle(thread.name))

    s.canonicalForStack(urlForThread(thread))
    reloadPostShareButtons()

    s.twitterForStack(twitterMetaForThread(thread))
    s.ogpForStack(ogpMetaForThread(thread))

    s.pushRecommendClue('threadIds', thread.id)
    s.pushRecommendClue('tagValues', Object.keys(thread.tags || {}))
    s.loadRecommendedThreads()
  }

  // --------------------
  // Handlers
  // --------------------

  handleLock () {
    const s = this
    const { l, props } = s
    const { use } = s.service('apiService')
    const { infoToast } = s.service('toastService')
    s.ifAuthorized((signed) => {
      let { threadId, thread } = props
      let locked = !thread.locked
      let attributes = Object.assign({}, thread, {
        locked
      })
      return s.applySpinWhile(() =>
        use('threadApi').then((threadApi) =>
          threadApi.update(threadId, attributes)
            .then(() => s.reloadThread())
            .then(() => {
              if (locked) {
                infoToast(l('toasts.THREAD_LOCK_SUCCESS'))
              } else {
                infoToast(l('toasts.THREAD_UNLOCK_SUCCESS'))
              }
            })
        )
      )
    })
  }

  handleEdit () {
    const s = this
    s.ifAuthorized((signed) => {
      const { props } = s
      let { threadId } = props
      s.handlePushToModal('ThreadEditView', {
        threadId
      })
    })
  }

  handleDestroy () {
    const s = this
    s.ifAuthorized((signed) => {
      const { props } = s
      let { threadId } = props
      s.handlePushToModal('ThreadDestroyView', {
        threadId
      })
    })
  }

  handleTag () {
    const s = this
    s.ifAuthorized((signed) => {
      const { props } = s
      let { threadId } = props
      s.handlePushToModal('ThreadTagView', {
        threadId
      })
    })
  }

  handlePost () {
    const s = this
    s.ifAuthorized((signed) => {
      const { props } = s
      let { threadId } = props
      return s.handlePushToModal('PostCreateView', {
        threadId
      })
    })
  }

  // --------------------
  // Dynamic variables
  // --------------------

  get detailUrl () {
    const s = this
    const { thread } = s.props
    const { absoluteUrl, urlForThread } = s.service('urlService')
    return thread && absoluteUrl(urlForThread(thread))
  }

  // --------------------
  // Custom
  // --------------------

  loadRecommendedThreads () {
    const s = this
    const { use } = s.service('apiService')
    const { setMemory } = s.service('memoryService')
    let { recommendClues: clues } = s.props
    return s.applySpinWhile({
      recommendSpinning: () =>
        use('threadApi').then((threadApi) =>
          threadApi.recommendations(clues)
            .then((recommendedThreads) =>
              setMemory('recommendedThreads', recommendedThreads)
            )
        )
    })
  }

}

export default combine(
  asServed(), forSpin(),
  forOne(),
  ofThread(),
  forEvent(),
  forCanonical(),
  forTwitter(),
  forOgp(),
  forAuth(),
  forTitle(),
  forRecommend(),
  asLocaled(), asView(),
  asConnected((state, { srvc }) => {
    const { getMemory } = srvc.memoryService
    return {
      recommendedThreads: getMemory('recommendedThreads')
    }
  })
)(ThreadDetailView)

