/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
'use strict'

import scroll from 'scroll-to'

let camelToKebab, appendStyle

const dom = {

  /**
   * createBody: create root component
   * @param  {object} element
   *    container|listview|scrollview
   * @return {[type]}      [description]
   */
  createBody: function (element) {
    const componentManager = this.getComponentManager()
    element.instanceId = componentManager.instanceId
    return componentManager.createBody(element)
  },

  addElement: function (parentRef, element, index) {
    const componentManager = this.getComponentManager()
    element.instanceId = componentManager.instanceId
    return componentManager.addElement(parentRef, element, index)
  },

  removeElement: function (ref) {
    const componentManager = this.getComponentManager()
    return componentManager.removeElement(ref)
  },

  moveElement: function (ref, parentRef, index) {
    const componentManager = this.getComponentManager()
    return componentManager.moveElement(ref, parentRef, index)
  },

  addEvent: function (ref, type) {
    const componentManager = this.getComponentManager()
    return componentManager.addEvent(ref, type)
  },

  removeEvent: function (ref, type) {
    const componentManager = this.getComponentManager()
    return componentManager.removeEvent(ref, type)
  },

  /**
   * updateAttrs: update attributes of component
   * @param  {string} ref
   * @param  {obj} attr
   */
  updateAttrs: function (ref, attr) {
    const componentManager = this.getComponentManager()
    return componentManager.updateAttrs(ref, attr)
  },

  /**
   * updateStyle: udpate style of component
   * @param {string} ref
   * @param {obj} style
   */
  updateStyle: function (ref, style) {
    const componentManager = this.getComponentManager()
    return componentManager.updateStyle(ref, style)
  },

  /**
   * scrollToElement
   * @param  {string} ref
   * @param  {obj} options {offset:Number}
   *   ps: scroll-to has 'ease' and 'duration'(ms) as options.
   */
  scrollToElement: function (ref, options) {
    !options && (options = {})
    const offset = Number(options.offset) || 0
    const elem = this.getComponentManager().getComponent(ref)
    if (!elem) {
      return console.error(`[h5-render] component of ref ${ref} doesn't exist.`)
    }
    const parentScroller = elem.getParentScroller()
    if (parentScroller) {
      parentScroller.scroller.scrollToElement(elem.node, true, offset)
    }
    else {
      const offsetTop = elem.node.getBoundingClientRect().top
          + document.body.scrollTop
      const tween = scroll(0, offsetTop + offset, options)
      tween.on('end', function () {
        console.log('scroll end.')
      })
    }
  },

  /**
   * getComponentRect
   * @param {string} ref
   * @param {function} callbackId
   */
  getComponentRect: function (ref, callbackId) {
    const info = { result: false }

    if (ref && ref === 'viewport') {
      info.result = true
      info.size = {
        width: document.documentElement.clientWidth,
        height: document.documentElement.clientHeight,
        top: 0,
        left: 0,
        right: document.documentElement.clientWidth,
        bottom: document.documentElement.clientHeight
      }
    }
    else {
      const elem = this.getComponentManager().getComponent(ref)
      if (elem && elem.node) {
        info.result = true
        info.size = elem.node.getBoundingClientRect()
      }
    }

    const message = info.result ? info : {
      result: false,
      errMsg: 'Illegal parameter'
    }
    this.sender.performCallback(callbackId, message)
    return message
  },

  /**
   * for adding fontFace
   * @param {string} key fontFace
   * @param {object} styles rules
   */
  addRule: function (key, styles) {
    key = camelToKebab(key)
    let stylesText = ''
    for (const k in styles) {
      if (styles.hasOwnProperty(k)) {
        stylesText += camelToKebab(k) + ':' + styles[k] + ';'
      }
    }
    const styleText = `@${key}{${stylesText}}`
    appendStyle(styleText, 'dom-added-rules')
  },

  createFinish (callback) {
    return this.getComponentManager().createFinish()
  },

  updateFinish (callback) {
    return this.getComponentManager().updateFinish()
  },

  refreshFinish (callback) {
    return this.getComponentManager().refreshFinish()
  }
}

const meta = {
  dom: [{
    name: 'createBody',
    args: ['object']
  }, {
    name: 'addElement',
    args: ['string', 'object', 'number']
  }, {
    name: 'removeElement',
    args: ['string']
  }, {
    name: 'moveElement',
    args: ['string', 'string', 'number']
  }, {
    name: 'addEvent',
    args: ['string', 'string']
  }, {
    name: 'removeEvent',
    args: ['string', 'string']
  }, {
    name: 'updateAttrs',
    args: ['string', 'object']
  }, {
    name: 'updateStyle',
    args: ['string', 'object']
  }, {
    name: 'createFinish',
    args: []
  }, {
    name: 'updateFinish',
    args: []
  }, {
    name: 'refreshFinish',
    args: []
  }, {
    name: 'scrollToElement',
    args: ['string', 'object']
  }, {
    name: 'getComponentRect',
    args: ['string', 'function']
  }, {
    name: 'addRule',
    args: ['string', 'object']
  }]
}

export default {
  init: function (Weex) {
    camelToKebab = Weex.utils.camelToKebab
    appendStyle = Weex.utils.appendStyle
    Weex.registerApiModule('dom', dom, meta)
  }
}
