/**
 * LandingTop view
 *
 * Generated by coz on 8/21/2016,
 * from a template provided by apeman-asset-templates.
 *
 * @class LandingTopView
 */
'use strict'

import React, { Component, PropTypes as types } from 'react'
import defineDebug from 'debug'
import {
  ApView, ApViewHeader, ApViewBody,
  ApContainer,
  ApSection, ApSectionHeader, ApSectionBody
} from 'apeman-react-basic'

import { LandingJumbotron, ThreadList, PostList, NewsList, Footer, Aside } from '../../fragments'
import { IconClasses, PreferenceFields } from 'ore-fol-enums'
import { asView, asConnected, asLocaled, asServed, forSpin, forList, forLink, forNews, combine } from '../../wrappers'
import { AssetSetting } from '../../../settings'

const { frontendJumbotron } = AssetSetting

const { THREAD_SORT } = PreferenceFields


const debug = defineDebug('project:view:landing-top')

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

  static get defaultProps () {
    return {}
  }

  render () {
    const s = this
    const {
      props,
      l
    } = s
    let {
      signed,
      threadsOfNew,
      threadsOfStar,
      postsOfNew,
      postsOfStar
    } = props

    return (
      <ApView id='landing-top-view'
              className='view'
              way={ props.way }
              headerless
      >
        <ApViewBody>
          <ApContainer>
            <div>
              <LandingJumbotron image={ frontendJumbotron }
                                signed={ signed }
                                onNewThread={ s.handleNewThread }
                                onSignin={ s.handleSignin }
                                onSignup={ s.handleSignup}
              />
            </div>
            <div className='landing-content aside-wrap'>
              <Aside ad
                     news={ props.latestNews }/>
              <LandingTopView.ThreadSection l={ l }
                                            caption={ l('headings.THREADS_OF_NEW') }
                                            threads={ threadsOfNew }
                                            onDetail={ s.handleThreadDetail }
                                            onMore={ s.handleThreadsOfNewMore }
              />

              <LandingTopView.ThreadSection l={ l }
                                            caption={ l('headings.THREADS_OF_STAR') }
                                            threads={ threadsOfStar }
                                            onDetail={ s.handleThreadDetail }
                                            onMore={ s.handleThreadsOfStarMore }
              />
              <LandingTopView.PostSection l={ l }
                                          caption={ l('headings.POSTS_OF_NEW') }
                                          posts={ postsOfNew }
                                          onDetail={ s.handlePostDetail }
              />

              <LandingTopView.PostSection l={ l }
                                          caption={ l('headings.POSTS_OF_STAR') }
                                          posts={ postsOfStar }
                                          onDetail={ s.handlePostDetail }
              />
              <div className="aside-alt">
                <LandingTopView.NewsSection l={ l }
                                            caption={ l('headings.LATEST_NEWS') }
                                            news={ props.latestNews }
                                            onMore={ s.handleNewsMore }
                />
              </div>
            </div>
          </ApContainer>
          <Footer/>
        </ApViewBody>
      </ApView>
    )
  }

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

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

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

    return Promise.all([
      s.loadThreads({}),
      s.loadPosts({})
    ])
  }

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

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

  handleSignin () {
    const s = this
    s.handlePushToModal('SignSignin')
  }

  handleSignup () {
    const s = this
    s.handlePushToModal('SignSignup')
  }

  handleNewThread () {
    const s = this
    const { urlForNewThread } = s.service('urlService')
    s.followLink(urlForNewThread())
  }

  handleThreadsOfNewMore () {
    const s = this
    const { urlForThreads } = s.service('urlService')
    const { setPreference } = s.service('preferenceService')
    setPreference(THREAD_SORT, 'ofNew')
    s.followLink(urlForThreads())
  }

  handleThreadsOfStarMore () {
    const s = this
    const { urlForThreads } = s.service('urlService')
    const { setPreference } = s.service('preferenceService')
    setPreference(THREAD_SORT, 'ofStar')
    s.followLink(urlForThreads())
  }

  handleThreadDetail (thread) {
    const s = this
    const { urlForThread } = s.service('urlService')
    s.followLink(urlForThread(thread))
  }

  handlePostDetail (post) {
    const s = this
    const { urlForPost } = s.service('urlService')
    s.followLink(urlForPost(post))
  }

  handleNewsMore () {
    const s = this
    const { urlForOtherViewName } = s.service('urlService')
    s.followLink(urlForOtherViewName('news-list-view'))
  }

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

  loadThreads ({ limit = 3 }) {
    const s = this
    const { use } = s.service('apiService')
    return use('threadApi').then((threadApi) =>
      s.applySpinWhile(() =>
        s.applyListLoad({
          threadsOfNew: () => threadApi.list({ sorter: 'ofNew', limit }),
          threadsOfStar: () => threadApi.list({ sorter: 'ofStar', limit })
        })
      )
    )
  }

  loadPosts ({ limit = 25 }) {
    const s = this
    const { use } = s.service('apiService')
    return use('postApi').then((postApi) =>
      s.applySpinWhile(() =>
        s.applyListLoad({
          postsOfNew: () => postApi.list({ sorter: 'ofNew', limit }),
          postsOfStar: () => postApi.list({ sorter: 'ofStar', limit })
        })
      )
    )
  }

  // --------------------
  // Sub Components
  // --------------------
  static ThreadSection ({ l, caption, threads, onDetail, onMore }) {
    return (
      <ApSection>
        <ApSectionHeader lined>{ caption }</ApSectionHeader>
        <ApSectionBody>
          {
            threads ? (
                <ThreadList threads={ threads.entities }
                            onDetail={ onDetail }
                            alt={ l('alt.NO_THREAD_FOUND') }
                            hasMore={ threads.more }
                            moreText={ l('buttons.SHOW_MORE') }
                            onMore={ onMore }
                            moreSpinning={ false }
                />
              ) : (
                <div className='landing-loading'>{ l('messages.NOW_LOADING') }</div>
              )
          }
        </ApSectionBody>
      </ApSection>
    )
  }

  static PostSection ({ l, caption, posts, onDetail, onMore }) {
    return (
      <ApSection>
        <ApSectionHeader lined>{ caption }</ApSectionHeader>
        <ApSectionBody>
          {
            posts ? (
                <PostList posts={ posts.entities }
                          onDetail={ onDetail }
                          alt={ l('alt.NO_POST_FOUND')}
                          hasMore={ false }
                          moreText={ l('buttons.SHOW_MORE') }
                          onMore={ onMore }
                          moreSpinning={ false }
                          simple
                />
              ) : (
                <div className='landing-loading'>{ l('messages.NOW_LOADING') }</div>
              )
          }
        </ApSectionBody>
      </ApSection>
    )
  }

  static NewsSection ({ l, caption, news, onMore }) {
    return (
      <ApSection className='landing-news-section'>
        <ApSectionHeader lined>{ caption }</ApSectionHeader>
        <ApSectionBody>
          {
            news ? (
                <NewsList news={ news.entities }
                          hasMore={ true }
                          moreText={ l('buttons.SHOW_MORE') }
                          onMore={ onMore }
                          moreSpinning={ false }
                />
              ) : (
                <div className='landing-loading'>{ l('messages.NOW_LOADING') }</div>
              )
          }
        </ApSectionBody>
      </ApSection>
    )
  }

}

export default combine(
  asServed(),
  forSpin(),
  forList(),
  forLink(),
  asLocaled(),
  asView(),
  forNews(),
  asConnected()
)(LandingTopView)

