import { defineComponent, onMounted, nextTick, ref, computed, resolveComponent, openBlock, createElementBlock, normalizeClass, createElementVNode, renderSlot, createCommentVNode, createBlock } from 'vue';
import { isEqual, isFunction } from 'lodash-es';
import { useTheme } from '../_theme/useTheme';
import getPrefixCls from '../_util/getPrefixCls';
import { useNormalModel } from '../_util/use/useModel';
import { UPDATE_MODEL_EVENT, CHANGE_EVENT } from '../_util/constants';
import useFormAdaptor from '../_util/use/useFormAdaptor';
import LoadingOutlined from '../icon/LoadingOutlined';

const prefixCls = getPrefixCls('switch');
const switchProps = {
  modelValue: {
    type: [String, Array, Object, Number, Boolean]
  },
  disabled: {
    type: Boolean,
    default: false
  },
  activeValue: {
    type: [String, Array, Object, Number, Boolean],
    default: true
  },
  inactiveValue: {
    type: [String, Array, Object, Number, Boolean],
    default: false
  },
  beforeChange: Function,
  size: {
    type: String,
    default: 'normal'
  }
};
var script = defineComponent({
  name: 'FSwitch',
  components: {
    LoadingOutlined
  },
  props: switchProps,
  emits: [UPDATE_MODEL_EVENT, CHANGE_EVENT],
  setup(props, ctx) {
    useTheme();
    const [currentValue, updateCurrentValue] = useNormalModel(props, ctx.emit, {
      prop: 'modelValue',
      isEqual: true
    });
    const {
      validate,
      isFormDisabled
    } = useFormAdaptor();
    onMounted(() => {
      // 默认为未选中，增加 props.inactiveValue 判断，避免 onMounted 设置初始值不生效
      if (currentValue.value === undefined && props.inactiveValue !== undefined) {
        // 避免可能出现的bug https://github.com/vuejs/core/issues/5290
        nextTick(() => {
          updateCurrentValue(props.inactiveValue);
        });
      }
    });
    const loadingRef = ref(false);
    const handleChange = () => {
      ctx.emit(CHANGE_EVENT, currentValue.value);
      validate(CHANGE_EVENT);
    };
    const activeRef = computed(() => isEqual(currentValue.value, props.activeValue));
    const inactiveRef = computed(() => isEqual(currentValue.value, props.inactiveValue));
    const innerDisabled = computed(() => props.disabled || isFormDisabled.value);
    const toggle = async () => {
      if (innerDisabled.value) {
        return;
      }
      if (isFunction(props.beforeChange)) {
        loadingRef.value = true;
        try {
          const confirm = await props.beforeChange(currentValue.value);
          loadingRef.value = false;
          if (confirm === false) {
            return;
          }
        } catch (e) {
          loadingRef.value = false;
          return;
        }
      }
      updateCurrentValue(activeRef.value ? props.inactiveValue : props.activeValue);
      handleChange();
    };
    const wrapperClass = computed(() => [prefixCls, props.size && `${prefixCls}-size-${props.size}`, activeRef.value && 'is-checked', innerDisabled.value && 'is-disabled'].filter(Boolean));
    return {
      prefixCls,
      wrapperClass,
      toggle,
      activeRef,
      inactiveRef,
      loadingRef
    };
  }
});

function render(_ctx, _cache, $props, $setup, $data, $options) {
  const _component_LoadingOutlined = resolveComponent("LoadingOutlined");
  return openBlock(), createElementBlock("div", {
    class: normalizeClass(_ctx.wrapperClass),
    onClick: _cache[0] || (_cache[0] = function () {
      return _ctx.toggle && _ctx.toggle(...arguments);
    })
  }, [createElementVNode("span", {
    class: normalizeClass(`${_ctx.prefixCls}-inner`)
  }, [_ctx.activeRef ? renderSlot(_ctx.$slots, "active", {
    key: 0
  }) : createCommentVNode("v-if", true), _ctx.inactiveRef ? renderSlot(_ctx.$slots, "inactive", {
    key: 1
  }) : createCommentVNode("v-if", true)], 2 /* CLASS */), _ctx.loadingRef ? (openBlock(), createBlock(_component_LoadingOutlined, {
    key: 0,
    class: normalizeClass(`${_ctx.prefixCls}-loading`)
  }, null, 8 /* PROPS */, ["class"])) : createCommentVNode("v-if", true)], 2 /* CLASS */);
}

script.render = render;
script.__file = "components/switch/switch.vue";

export { script as default, switchProps };
