/**
 * Toast group.
 * @class ApToastGroup
 */

'use strict'

import React, {PropTypes as types} from 'react'
import {shallowEqual, deepEqual} from 'asobj'
import ApToast from './ap_toast'
import ApInfoToast from './ap_info_toast'
import ApWarnToast from './ap_warn_toast'
import ApErrorToast from './ap_error_toast'
import classnames from 'classnames'

let levels = [
  'default', 'info', 'error', 'warn'
]

/** @lends ApToastGroup */
const ApToastGroup = React.createClass({

  // --------------------
  // Specs
  // --------------------

  propTypes: {
    /** Default messages */
    default: types.arrayOf(types.string),
    /** Info messages */
    info: types.arrayOf(types.string),
    /** Error messages */
    error: types.arrayOf(types.string),
    /** Warn messages */
    warn: types.arrayOf(types.string),
    /** Dismiss message */
    dismiss: types.func
  },

  mixins: [],

  statics: {
    levels
  },

  getInitialState () {
    return {}
  },

  getDefaultProps () {
    return {
      info: [],
      error: [],
      warn: []
    }
  },

  render () {
    const s = this
    let { state, props } = s
    let {
      default: default_,
      className, info, error, warn, dismiss
    } = props

    return (
      <div className={ classnames('ap-toast-group', {}, className) }>
        <ApToast messages={ default_ } dismiss={ (message) => dismiss(message, 'default') }/>
        <ApInfoToast messages={ info } dismiss={ (message) => dismiss(message, 'info') }/>
        <ApWarnToast messages={ warn } dismiss={ (message) => dismiss(message, 'warn') }/>
        <ApErrorToast messages={ error } dismiss={ (message) => dismiss(message, 'error') }/>
        { props.children }
      </div>
    )
  },

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

  componentDidMount () {
    const s = this
    let { props } = s
  },

  componentWillReceiveProps (nextProps) {
    const s = this
    let { props } = s
  },

  componentWillUnmount () {
    const s = this
    let { props } = s
  },

  shouldComponentUpdate (nextProps, nextState) {
    const s = this
    let { props, state } = s
    for (let level of levels) {
      let messageChanged = deepEqual(props[ level ], nextProps[ level ])
      if (messageChanged) {
        return true
      }
    }
    return !shallowEqual(props, nextProps) || shallowEqual(state, nextState)
  },

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

  handleDismiss (e) {
    const s = this
    let { state } = s
    let { name, dismissed } = e
    if (state[ name ] === dismissed) {
      s.setState({ name: null })
    }
  },

  /**
   * Bind toaster events.
   * @param toaster
   */
  bindToaster (toaster) {
    const s = this
    toaster.addListener('toast', s.handleToast)
  },

  /**
   * Unbind toaster events.
   * @param toaster
   */
  unbindToaster (toaster) {
    const s = this
    toaster.removeListener('toast', s.handleToast)
  },

  /**
   * Handle toaster events.
   * @param data
   */
  handleToast (data) {
    const s = this
    let state = { _date: new Date() }
    Toaster.levels.forEach((level) => {
      state[ level ] = data.level === level ? data.message : null
    })
    s.setState(state)
  }
})

export default ApToastGroup
