/**
 * apeman react package for icon components.
 * @class ApIcon
 */

'use strict'

import React, {PropTypes as types} from 'react'
import {ApPureMixin} from 'apeman-react-mixins'
import classnames from 'classnames'

let assertCache = {}
let notfoundCache = []

const ASSERT_DELAY = 400

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

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

  propTypes: {},

  mixins: [
    ApPureMixin
  ],

  statics: {
    /**
     * Check if has style.
     * @param className
     */
    hasStyleWithClass (className) {
      let styleSheets = document.styleSheets || []
      for (let i = 0; i < styleSheets.length; i++) {
        let styleSheet = styleSheets[ i ]
        let rules = styleSheet.rules || styleSheet.cssRules || []
        for (let j = 0; j < rules.length; j++) {
          let rule = rules[ j ]
          let selectorText = rule.selectorText
          let hit = selectorText && new RegExp(`\.${className}`).test(selectorText)
          if (hit) {
            return true
          }
        }
      }
      return false
    },

    warnNotFound () {
      setTimeout(() => {
        if (notfoundCache.length > 0) {
          console.warn(
`[ApIcon] No style found for class ${notfoundCache.map((notFound) => `"${notFound}"`).join(', ')}.
You seeing this warning either because of:
  1. Misspelling the name or missing some stylesheets.
  2. Using stylesheets from another domain.`
          )
          notfoundCache = []
        }
      }, 100)
    },
    ASSERT_DELAY
  },

  getInitialState () {
    return {}
  },

  getDefaultProps () {
    return {}
  },

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

    return (
      <i className={ classnames('ap-icon', props.className) }
         style={Object.assign({}, props.style)}>
      </i>
    )
  },

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

  componentDidMount () {
    const s = this
    s.mounted = true
    let { props } = s
    s.assertClassName(props.className, { delay: 1200 })
  },

  componentWillReceiveProps (nextProps) {
    const s = this
    if (nextProps.hasOwnProperty('className')) {
      s.assertClassName(nextProps.className)
    }
  },

  componentWillUnmount () {
    const s = this
    clearTimeout(s._assertTimer)
  },

  // ------------------
  // Helper
  // ------------------

  assertClassName (className, options = {}) {
    if (!className) {
      return
    }
    const s = this
    clearTimeout(s._assertTimer)
    s._assertTimer = setTimeout(() => {
      if (!s.mounted) {
        return
      }
      className.split(/\s/g).forEach((className) => {
        if (!className) {
          return
        }
        if (assertCache.hasOwnProperty(className)) {
          return
        }
        if (/^ap/.test(className)) {
          return
        }
        let valid = ApIcon.hasStyleWithClass(className)
        if (!valid) {
          notfoundCache.push(className)
        }
        assertCache[ className ] = valid
      })
      ApIcon.warnNotFound()
    }, options.delay || ASSERT_DELAY)
  },

  // ------------------
  // Private
  // ------------------

  _assertTimer: -1
})

export default ApIcon
