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

import React, { Component, PropTypes as types } from 'react'
import defineDebug from 'debug'
import {
  ApView, ApViewHeader, ApViewBody
} from 'apeman-react-basic'
import {
  asConnected,
  asLocaled,
  asView,
  asServed,
  forOne,
  forSpin,
  forEntry,
  forAuth,
  forEvent,
  ofPost,
  ofSigned,
  combine
} from '../../wrappers'

import { IconClasses } from 'ore-fol-enums'
import { ReportForm, PostCard } from '../../fragments'
import { ReportTypeCodes } from 'ore-fol-codes'

const { REPORT_ICON } = IconClasses
const {
  POST_INAPPROPRIATE,
  POST_VIOLATION,
  POST_WRONG_THREAD,
  POST_OTHER_REASON
} = ReportTypeCodes

const debug = defineDebug('project:view:post-report')

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

  static get defaultProps () {
    return {}
  }

  render () {
    const s = this
    const {
      props,
      labels,
      errors,
      reportTypes,
      l,
    } = s
    let {
      post
    } = props
    let target = post ? (
        <PostCard post={ post }/>
      ) : null
    return (
      <ApView id='post-report-view'
              className='view'
              spinning={ props.spinning }
              way={ props.way }
      >
        <ApViewHeader onLeftTap={ s.handlePop }
                      leftText={ null }
                      leftIcon={ props.popIcon }
                      titleText={ l('titles.REPORT') }
                      titleIcon={ REPORT_ICON }
                      onRightTap={ null }
                      rightIcon={ null }
                      rightText={ null }
        />

        <ApViewBody>
          <ReportForm labels={ labels }
                      values={ props.entryValues }
                      errors={ errors }
                      onSubmit={ s.handleSubmit }
                      onTakeback={ s.handleTakeback }
                      onUpdate={ s.handleEntryUpdate }
                      reportTypes={ types }
                      target={ target }
          />
        </ApViewBody>
      </ApView>
    )
  }

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

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

  componentDidMount () {
    debug('didMount')
    const s = this
    const { props } = s
    let {
      reportType: type = POST_INAPPROPRIATE
    } = props
    s.handleEntryUpdate({
      type,
      has: null
    })
  }

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

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

  handleSubmit () {
    const s = this
    const { use } = s.service('apiService')
    const { infoToast } = s.service('toastService')
    const { props, l } = s
    let {
      postId,
      entryValues = {}
    } = props
    let { text, type } = entryValues
    return s.applySpinWhile(() =>
      use('reportApi')
        .then((reportApi) =>
          reportApi.createOwnForPost(postId, {
            type,
            text
          })
        )
        .then(() => {
          infoToast(l('toasts.REPORT_SUCCESS'))
          return s.handlePop()
            .then(s.handleEntryClear)
        })
        .catch(s.handleEntryErrorCatch)
    )
  }

  handleTakeback () {
    const s = this
    const { use } = s.service('apiService')
    const { infoToast } = s.service('toastService')
    const { props, l } = s
    let {
      postId
    } = props
    return s.applySpinWhile(() =>
      use('reportApi')
        .then((reportApi) =>
          reportApi.destroyOwnForPost(postId)
        )
        .then(() => {
          infoToast(l('toasts.REPORT_TAKEBACK_SUCCESS'))
          return s.handlePop()
            .then(s.handleEntryClear)
        })
    )
  }

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

  postDidLoad ({ id: postId }) {
    const s = this
    s.loadHasReport(postId)
  }

  // --------------------
  // Dynamic variables
  // --------------------
  get labels () {
    const s = this
    const { l, props } = s
    const { relativeDateString } = s.service('localeService')
    const { has } = (props.entryValues || {})
    return {
      target: l('labels.REPORT_TARGET'),
      type: l('labels.REPORT_TYPE'),
      text: l('labels.REPORT_TEXT'),
      submit: l('buttons.DO_REPORT'),
      takeback: l('buttons.DO_REPORT_TAKEBACK'),
      has: l('messages.POST_ALREADY_REPORTED', {
        vars: { at: has && relativeDateString(has.createdAt) }
      })
    }
  }

  get reportTypes () {
    const s = this
    const { l } = s
    return {
      [POST_VIOLATION]: l('labels.REPORT_VIOLATION'),
      [POST_INAPPROPRIATE]: l('labels.REPORT_INAPPROPRIATE'),
      [POST_WRONG_THREAD]: l('labels.REPORT_WRONG_THREAD'),
      [POST_OTHER_REASON]: l('labels.REPORT_OTHER_REASON')
    }
  }

  get errors () {
    const s = this
    const { labels, props } = s
    const { localizeErrors } = s.service('localeService')
    return localizeErrors(props.entryErrors, { labels })
  }

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

  loadHasReport (postId) {
    const s = this
    const { use } = s.service('apiService')
    return s.applySpinWhile(() =>
      use('reportApi').then((reportApi) =>
        reportApi.listOwnForPost(postId)
          .then(({ entities: reports }) =>
            s.handleEntryUpdate({
              has: reports && reports[ 0 ]
            })
          )
      )
    )
  }
}

export default combine(
  asServed(),
  forSpin(),
  forOne(),
  forAuth(),
  forEntry(),
  ofPost(),
  asLocaled(),
  asView(),
  forEvent(),
  ofSigned(),
  asConnected()
)(PostReportView)

