import $ from "jquery";
import "shiny";
import { updateLabel } from "../modules/utils";
import noUiSlider from "nouislider";
import "nouislider/dist/nouislider.css";
import wNumb from "wnumb";


var noUiSliderBinding = new Shiny.InputBinding();
$.extend(noUiSliderBinding, {
  find: function find(scope) {
    return $(scope).find(".sw-no-ui-slider");
  },
  getId: function getId(el) {
    return el.id;
  },
  getType: function getType(el) {
    var dataType = $(el).data("data-type");
    if (dataType === "date") return "shiny.date";
    else if (dataType === "datetime") return "shiny.datetime";
    else return false;
  },
  getValue: function getValue(el) {
    var slider = document.getElementById(el.id);
    var values = slider.noUiSlider.get();
    var result;

    var $el = $(el);
    var config = $el
      .parent()
      .find('script[data-for="' + Shiny.$escape(el.id) + '"]');
    config = JSON.parse(config.html());
    if (typeof config.format !== "undefined") {
      var numformat = wNumb(config.format);
      if (Array.isArray(values)) {
        result = values.map(numformat.from);
      } else {
        result = numformat.from(values);
      }
    } else {
      if (Array.isArray(values)) {
        result = values.map(Number);
      } else {
        result = Number(values);
      }
    }
    //var result = values.map(Number);
    return result;
  },
  setValue: function setValue(el, value) {
    var slider = document.getElementById(el.id);
    slider.noUiSlider.set(value);
  },
  subscribe: function subscribe(el, callback) {
    var slider = document.getElementById(el.id);
    var update_on = $("#" + el.id).data("update");
    if (update_on == "end") {
      slider.noUiSlider.on("change", function(event) {
        callback();
      });
      slider.noUiSlider.on("set", function(event) {
        callback();
      });
    } else {
      slider.noUiSlider.on("slide", function(event) {
        callback();
      });
      slider.noUiSlider.on("set", function(event) {
        callback();
      });
    }
  },
  unsubscribe: function unsubscribe(el) {
    $(el).off(".noUiSliderBinding");
  },
  receiveMessage: function receiveMessage(el, data) {

    if (data.hasOwnProperty("label")) {
      var label = $("#" + el.id + "-label");
      updateLabel(data.label, label);
    }

    var slider = document.getElementById(el.id);
    if (data.hasOwnProperty("range")) {
      slider.noUiSlider.updateOptions({
        range: {
          min: data.range[0],
          max: data.range[1]
        }
      });
    }
    slider.noUiSlider.set(data.value);
    if (data.hasOwnProperty("disable")) {
      if (data.disable) {
        slider.noUiSlider.disable();
      } else {
        slider.noUiSlider.enable();
      }
    }
    if (data.hasOwnProperty("disableHandlers")) {
      for (let i = 0; i < data.disableHandlers.length; i++) {
        slider.noUiSlider.disable(data.disableHandlers[i] - 1);
      }
    }
    if (data.hasOwnProperty("enableHandlers")) {
      for (let i = 0; i < data.enableHandlers.length; i++) {
        slider.noUiSlider.enable(data.enableHandlers[i] - 1);
      }
    }
    $(el).trigger("change");
  },
  getRatePolicy: function getRatePolicy() {
    return {
      policy: "debounce",
      delay: 250
    };
  },
  getState: function getState(el) {},
  initialize: function initialize(el) {
    var $el = $(el);
    var config = $el
      .parent()
      .find('script[data-for="' + Shiny.$escape(el.id) + '"]');
    config = JSON.parse(config.html());
    if (config.hasOwnProperty("format")) {
      config.format = wNumb(config.format);
    }
    if (config.hasOwnProperty("pips")) {
      if (config.pips.hasOwnProperty("format")) {
        config.pips.format = wNumb(config.pips.format);
      }
      if (config.pips.hasOwnProperty("size")) {
        config.pips.filter = function(value, type) {
          if (type > 0) {
            return config.pips.size;
          } else {
            return type;
          }
        };
      }
    }
    var slider = document.getElementById(el.id);
    if (config.orientation === "vertical") {
      slider.style.margin = "0 auto 30px";
    }
    noUiSlider.create(slider, config);
  }
});

Shiny.inputBindings.register(noUiSliderBinding, "shinyWidgets.noUiSlider");
