/**
 * apeman react package for head component.
 * @class ApHead
 */

'use strict'

import React, {PropTypes as types} from 'react'
import stringcase from 'stringcase'

/** @lends ApHead */
const ApHead = React.createClass({
  // --------------------
  // Specs
  // --------------------

  propTypes: {
    /** CharSet */
    charset: types.string,
    /** Document Title */
    title: types.string,
    /** Favicon */
    icon: types.string,
    /** Meta data */
    meta: types.oneOfType([
      types.arrayOf(types.object),
      types.object
    ]),
    /** Micro data settings */
    itemProps: types.oneOfType([
      types.arrayOf(types.object),
      types.object
    ]),
    /** CSS file urls */
    css: types.array,
    /** JS file urls */
    js: types.array,
    /** Version string */
    version: types.string,
    /** Querystring key for version */
    versionKey: types.string,
    /** Global variables */
    globals: types.object,
    /** View port settings */
    viewport: types.object
  },

  mixins: [],

  statics: {
    renderCharset (charset) {
      if (!charset) {
        return null
      }
      return (
        <meta className="ap-head-meta" charSet={charset}/>
      )
    },
    renderTitle (title) {
      if (!title) {
        return null
      }
      return (
        <title className="ap-head-title">{title}</title>
      )
    },
    renderIcon (url, query) {
      if (!url) {
        return null
      }
      return (
        <link rel="icon" href={ ApHead._addQuery(url, query) }/>
      )
    },
    renderMetaValues (values) {
      if (!values) {
        return null
      }
      return [].concat(values).map((values, i) =>
        Object.keys(values).map((name, j) =>
          <meta name={ name }
                content={ values[name] }
                key={ `meta-${i}-${j}` }/>
        )
      ).reduce((a, b) => [].concat(a, b), [])
    },
    renderItemProps (values) {
      if (!values) {
        return null
      }
      return [].concat(values).map((values, i) =>
        Object.keys(values).map((name, j) =>
          <meta itemProp={ name }
                content={ values[name] }
                key={ `item-prop${i}-${j}` }/>
        )
      ).reduce((a, b) => [].concat(a, b), [])
    },
    renderCss (urls, query) {
      if (!urls) {
        return null
      }
      return [].concat(urls).map((url, i) =>
        <link rel="stylesheet"
              type="text/css"
              key={ `css-${i}-${url}` }
              href={ ApHead._addQuery(url, query) }/>
      )
    },
    renderJs (urls, query) {
      if (!urls) {
        return null
      }
      return [].concat(urls).map((url, i) =>
        <script type="text/javascript"
                key={ `js-${i}-${url}` }
                src={ ApHead._addQuery(url,query)}></script>
      )
    },
    renderGlobals (values) {
      let _stringify = (data) => data ? JSON.stringify(data || {}) : "null"

      return Object.keys(values || {}).map((key, i) =>
        <script type="text/javascript"
                key={ `global-${i}-${key}` }
                dangerouslySetInnerHTML={
                    {__html: `window.${key}=${_stringify(values[key])}`}
                    }></script>
      )
    },
    renderViewPort (values) {
      let content = Object.keys(values || {}).map((key) =>
        [ stringcase.spinalcase(key), values[ key ] ].join('=')
      ).join(',')
      return <meta name="viewport" content={ content }/>
    },
    _addQuery (url, query) {
      let joiner = /\?/.test(url) ? '&' : '?'
      return [ url, query ].join(joiner)
    }
  },

  getInitialState () {
    return {}
  },

  getDefaultProps () {
    return {
      version: 'unknown',
      versionKey: 'v',
      viewport: {
        width: 'device-width',
        initialScale: '1.0'
      }
    }
  },

  render () {
    const s = this
    let { props } = s

    let query = [ props.versionKey, props.version ].join('=')
    return (
      <head className="ap-head">
        { ApHead.renderCharset(props.charset) }
        { ApHead.renderTitle(props.title) }
        { ApHead.renderMetaValues(props.meta) }
        { ApHead.renderItemProps(props.itemProps) }
        { ApHead.renderIcon(props.icon, query) }
        { ApHead.renderJs(props.js, query) }
        { ApHead.renderCss(props.css, query) }
        { ApHead.renderGlobals(props.globals) }
        { ApHead.renderViewPort(props.viewport) }
        { props.children }
      </head>
    )
  }
})

export default ApHead
