'use strict';

var m = require('mithril');
var isFunction = require('lodash/lang/isFunction');
var assign = require('lodash/object/assign');
var minMax = require('client/utils').minMax;

var content, targetDimensions, options, showTimer, isVisible;

function px(value) {
  return value + 'px';
}

function show(_content, _options) {
  var wrapInRedraw = require('client/utils/viewhelper').wrapInRedraw;

  return function(event) {
    targetDimensions = event.currentTarget.getBoundingClientRect();
    options = assign({
      position: 'bottom',
      delay: 500
    }, _options);
    content = _content;
    showTimer = setTimeout(wrapInRedraw(function() {
      isVisible = true;
    }), options.delay);
  };
}

function hide() {
  clearTimeout(showTimer);
  isVisible = false;
}

function withTooltip(el, content, options) {
  el.attrs.onmouseenter = show(content, assign({
    position: 'bottom',
    delay: 500
  }, options));
  el.attrs.onmouseout = hide;
  return el;
}

function view() {
  var classy = require('client/utils/viewhelper').classy;

  if (!content) {
    return;
  }
  var classes = {
    'tooltip-hidden': !isVisible,
    'tooltip-dark': options.dark
  };
  classes['tooltip-' + options.position] = true;
  return m('.tooltip', {
    className: classy(classes),
    config: function(element) {
      var contentDimensions = element.getBoundingClientRect();
      var targetVerticalCenter = targetDimensions.top + targetDimensions.height/2;
      var targetHorizontalCenter = targetDimensions.left + targetDimensions.width/2;

      // ensure that bubble is on screen
      if (targetHorizontalCenter + contentDimensions.width / 2 > window.innerWidth) {
        options.position = 'left';
      }
      if (targetHorizontalCenter - contentDimensions.width / 2 < 0) {
        options.position = 'right';
      }
      if (targetVerticalCenter - contentDimensions.height / 2 < 0) {
        options.position = 'bottom';
      }
      if (targetVerticalCenter + contentDimensions.height / 2 > window.innerHeight) {
        options.position = 'top';
      }

      // default bottom
      var left = targetHorizontalCenter - contentDimensions.width/2;
      var top = targetDimensions.bottom;
      if (options.position === 'right') {
        left = targetDimensions.right;
        top = targetVerticalCenter - contentDimensions.height/2;
      } else if (options.position === 'top') {
        left = targetHorizontalCenter - contentDimensions.width/2;
        top = targetDimensions.top - contentDimensions.height;
      } else if (options.position === 'left') {
        left = targetDimensions.left - contentDimensions.width;
        top = targetVerticalCenter - contentDimensions.height/2;
      }

      // again ensure that bubble is on screen in case it's in one of the screen edges
      left = minMax(0, left, window.innerWidth - contentDimensions.width);
      top = minMax(0, top, window.innerHeight - contentDimensions.height);

      element.style.left = px(Math.floor(window.scrollX + left));
      element.style.top = px(Math.floor(window.scrollY + top));
    }
  }, isFunction(content) ? content() : content);
}

module.exports = {
  show: show,
  hide: hide,
  view: view,
  withTooltip: withTooltip
};