/**
 * Higher order component with spinner
 * @function withSpin
 * @param {function} Component - A component constructor
 * @returns {function} - Wrapped component
 */
'use strict'

import {wrap} from 'breact'
import {clone} from 'asobj'
import ApSpinner from './ap_spinner'
import React, {PropTypes as types} from 'react'

/** @lends withSpin */
function withSpin (Component) {
  const propTypes = {
    /** Show loading spinner */
    spinning: types.bool,
    /** Theme of the spinner */
    spinnerTheme: types.string,
    /** Size of spinner */
    spinnerSize: types.string,
    /** Spinner instance */
    spinner: types.node
  }
  return wrap(Component, {
    displayName: 'withSpin',

    propTypes,

    getDefaultProps () {
      return {
        spinning: false,
        spinnerTheme: ApSpinner.DEFAULT_THEME,
        spinnerSize: 'x-large',
        spinner: undefined
      }
    },

    render () {
      const s = this
      let { props } = s
      let {
        spinnerTheme,
        spinnerSize,
        spinning,
        spinner = (
          <ApSpinner theme={ spinnerTheme }
                     className='ap-spinner-cover'
                     size={ spinnerSize }
                     enabled={ spinning }/>
        )
      } = props
      let componentProps = clone(props, {
        without: Object.keys(propTypes)
      })
      return (
        <Component { ...componentProps }
                   spinner={ spinner }
        >
          { props.children }
        </Component>
      )
    }
  })
}

export default withSpin
