import { CocoComponent } from "@assets/js/coco/component.js";
import { camelCase } from "@helpers/lang";

export default CocoComponent("button", (data = {}) => {
  return {
    options: ["state", "confirm", "size", "disabled", "collapsible"],

    isCollapsed: false,
    approving: false,
    confirmed: true,
    lastState: null,
    stateTooltips: data.tooltips || {},
    tooltipText: null,

    ...(data.props || {}),

    init() {
      this.lastState = this.state;
      this.checkConfirmation = this.checkConfirmation.bind(this);
      this.approveAndRun = this.approveAndRun.bind(this);
      this.shouldShowTooltip = this.shouldShowTooltip.bind(this);

      this.$nextTick(() => {
        if (this.$options.confirm) {
          this.confirmed = false;
        }
      });

      this.$watch("collapsed", (collapsed) => {
        if (collapsed && !this.collapsible) {
          this.collapsed = false;
          return;
        }

        this.$root.setAttribute("data-collapsed", collapsed ? "true" : "false");
      });
    },

    setTooltipText() {
      if (this.disabled) {
        this.tooltipText = null;
        return;
      }

      const defaultContent = this.$el.getAttribute("data-tippy-content");
      const tooltipForState = this.stateTooltips[this.state];

      if (this.collapsed) {
        // Show the supplied tooltip if any was set,
        // otherwise use the button label text instead.
        const labelText = this.getContentForState(this.state);
        this.tooltipText = tooltipForState || labelText || defaultContent;
      } else {
        this.tooltipText = tooltipForState || defaultContent;
      }
    },

    shouldShowTooltip() {
      return !!this.tooltipText;
    },

    get disabled() {
      return this.$options.disabled === true;
    },

    set disabled(value) {
      this.$options.disabled = value;
    },

    get tippyInstance() {
      return this.$root.__x_tippy;
    },

    /* confirmation */

    checkConfirmation(event) {
      if (!this.confirmed) {
        this.approving = true;
        event.preventDefault();
      }
    },

    approveAndRun(event) {
      if (this.approving) {
        event.stopPropagation();
        this.confirmed = true;
        this.dropdown.trigger.click();
        this.dropdown.hide();
        this.confirmed = false;
        this.approving = false;
      }
    },

    cancelConfirmation(event) {
      if (this.approving) {
        event.stopPropagation();
        this.approving = false;
        this.dropdown.hide();
      }
    },

    /* state */

    get state() {
      return this.$options.state || "default";
    },

    set state(name) {
      this.setState(name);
    },

    get loading() {
      return this.state === "loading";
    },

    set loading(value) {
      this.$options.state = value === true ? "loading" : "default";
    },

    setState(name) {
      this.lastState = this.state;
      this.$options.state = camelCase(name);
    },

    resetState() {
      this.$options.state = this.lastState || "default";
      this.lastState = this.$options.state;
    },

    toggleState(state1, state2 = this.laststate) {
      this.state = this.state === state1 ? state2 : state1;
    },

    getContentForState(state) {
      const content = this.$refs[`${state}Content`];
      return content ? content.innerText : null;
    },

    hasIconForState(state) {
      return !!this.$refs[`${state}Icon`];
    },

    hasContentForState(state) {
      return !!this.getContentForState(state);
    },

    showIcon(state) {
      return (
        state === this.state ||
        (!this.hasIconForState(this.state) && state === "default")
      );
    },

    showContent(state) {
      return (
        state === this.state ||
        (!this.hasContentForState(this.state) && state === "default")
      );
    },

    /* collapsing */

    get collapsed() {
      return this.isCollapsed;
    },

    set collapsed(value) {
      this.isCollapsed = this.collapsible ? value : false;
    },

    get collapsible() {
      return (
        this.$options.collapsible !== false &&
        this.hasIconForState(this.$options.state || "default")
      );
    },

    /* bindings */

    root: {
      "x-options": "options",
      "x-tooltip": "tooltipText",
      "x-effect": "setTooltipText",
      ":disabled": "disabled",
    },
  };
});