import { defineComponent, ref, computed, watch, inject, watchEffect, provide, createElementBlock, openBlock, normalizeStyle, normalizeClass, unref, createBlock, createElementVNode, createVNode, withCtx, createCommentVNode, Fragment, renderList, createTextVNode, toDisplayString, renderSlot, Teleport, withDirectives, vShow, createSlots } from "vue";
import { defaultSize } from "../_utils/global.mjs";
import { IconClose, IconLoading, IconChevronDown } from "../_utils/icons.mjs";
import { OPopup } from "../popup/index.mjs";
import { OPopover } from "../popover/index.mjs";
import { ODialog } from "../dialog/index.mjs";
import { selectOptionInjectKey } from "./provide.mjs";
import { selectProps } from "./types.mjs";
import { getRoundClass } from "../_utils/style-class.mjs";
import ClientOnly from "../_components/client-only.mjs";
import { OScroller } from "../scrollbar/index.mjs";
import { isArray, isUndefined, isArrayEqual, isFunction } from "../_utils/is.mjs";
import _sfc_main$1 from "./SelectOption.vue.mjs";
import slot from "./slot.mjs";
import { filterSlots } from "../_utils/vue-utils.mjs";
import { formItemInjectKey } from "../form/provide.mjs";
import { useI18n } from "../locale/index.mjs";
import { OButton } from "../button/index.mjs";
import { useScreen } from "../hooks/use-screen.mjs";
const _hoisted_1 = ["value", "placeholder"];
const _hoisted_2 = { class: "o-select-tags-wrap" };
const _hoisted_3 = ["onClick"];
const _hoisted_4 = { class: "o-select-tags" };
const _hoisted_5 = ["onClick"];
const _hoisted_6 = { class: "o-select-suffix" };
const _hoisted_7 = { class: "o-select-suffix-icon" };
const _hoisted_8 = {
  key: 0,
  class: "o-select-loading"
};
const _hoisted_9 = { class: "o-select-option-wrap" };
const _hoisted_10 = { class: "o-select-empty" };
const _hoisted_11 = { class: "o-select-options-head" };
const _sfc_main = /* @__PURE__ */ defineComponent({
  __name: "OSelect",
  props: selectProps,
  emits: ["update:modelValue", "change", "options-visible-change", "clear"],
  setup(__props, { emit: __emit }) {
    const props = __props;
    const emits = __emit;
    const { isPhonePad } = useScreen();
    const { t } = useI18n();
    const selectRef = ref();
    const optionsRef = ref(null);
    const isSelecting = ref(false);
    const isResponding = computed(() => {
      return !props.noResponsive && isPhonePad.value;
    });
    const tagPopoverVisible = ref(false);
    watch(
      () => isSelecting.value,
      () => {
        if (isSelecting.value) {
          tagPopoverVisible.value = false;
        }
      }
    );
    const formItemInjection = inject(formItemInjectKey, null);
    const color = computed(() => {
      var _a;
      if (formItemInjection == null ? void 0 : formItemInjection.fieldResult.value) {
        return (_a = formItemInjection == null ? void 0 : formItemInjection.fieldResult.value) == null ? void 0 : _a.type;
      } else {
        return props.color;
      }
    });
    const optionLabels = ref({});
    const valueList = ref([]);
    const finalValueList = ref([]);
    if (isArray(props.modelValue)) {
      valueList.value = [...props.modelValue];
    } else if (isArray(props.defaultValue)) {
      valueList.value = [...props.defaultValue];
    } else {
      const mrValue = props.modelValue ?? props.defaultValue;
      if (!isUndefined(mrValue)) {
        valueList.value = [mrValue];
      } else {
        valueList.value = [];
      }
    }
    finalValueList.value = [...valueList.value];
    const valueListDisplay = computed(() => {
      if (!props.maxTagCount) {
        return finalValueList.value;
      }
      return finalValueList.value.slice(0, props.maxTagCount);
    });
    const valueListFold = computed(() => {
      if (!props.maxTagCount) {
        return [];
      }
      return finalValueList.value.slice(props.maxTagCount);
    });
    const foldLabel = computed(() => {
      if (props.foldLabel) {
        const tags = valueListFold.value.map((item) => ({
          value: item,
          label: optionLabels.value[item]
        }));
        return props.foldLabel(tags);
      }
      return `+${valueListFold.value.length}...`;
    });
    const foldTrigger = typeof props.showFoldTags === "string" ? props.showFoldTags : "hover";
    const round = getRoundClass(props, "select");
    watch(
      () => props.modelValue,
      (v) => {
        if (props.multiple) {
          if (isArray(v)) {
            if (!isArrayEqual(v, valueList.value)) {
              valueList.value = [...v];
            }
          } else {
            valueList.value = [];
          }
        } else if (valueList.value[0] !== v) {
          valueList.value = [v];
        }
        finalValueList.value = [...valueList.value];
      }
    );
    watchEffect(() => {
      if (!isResponding.value) {
        finalValueList.value = [...valueList.value];
      }
    });
    const isClearable = computed(() => props.clearable && !props.disabled && valueList.value.length > 0);
    const emitChange = (value) => {
      var _a, _b;
      if (props.multiple) {
        emits("change", [...value]);
      } else {
        emits("change", value[0]);
      }
      (_b = formItemInjection == null ? void 0 : (_a = formItemInjection.fieldHandlers).onChange) == null ? void 0 : _b.call(_a);
    };
    const emitUpdateValue = (value) => {
      if (props.multiple) {
        emits("update:modelValue", [...value]);
      } else {
        emits("update:modelValue", value[0]);
      }
    };
    const clearClick = (e) => {
      e.stopPropagation();
      valueList.value = [];
      emits("clear", e);
      emitChange(valueList.value);
      emitUpdateValue(valueList.value);
    };
    const beforeSelect = async (value) => {
      if (isFunction(props.beforeSelect)) {
        const rlt = await props.beforeSelect(value, props.multiple ? valueList.value : valueList.value[0]);
        return rlt;
      }
      return true;
    };
    provide(selectOptionInjectKey, {
      multiple: props.multiple,
      selectValue: valueList,
      select: async (option, userSelect) => {
        if (userSelect) {
          let toValue = option.value;
          const rlt = await beforeSelect(option.value);
          if (rlt === false) {
            return;
          }
          if (typeof rlt !== "boolean") {
            toValue = rlt;
          }
          if (!props.multiple) {
            isSelecting.value = false;
            if (valueList.value[0] !== toValue) {
              valueList.value[0] = toValue;
              emitUpdateValue(valueList.value);
              emitChange(valueList.value);
            }
          } else {
            const idx = valueList.value.indexOf(toValue);
            if (idx > -1) {
              valueList.value.splice(idx, 1);
            } else {
              valueList.value.push(toValue);
            }
            if (!isResponding.value) {
              emitUpdateValue(valueList.value);
              emitChange(valueList.value);
            }
          }
        } else {
          if (optionLabels.value[option.value] !== option.label) {
            optionLabels.value[option.value] = option.label;
          }
        }
      }
    });
    const onOptionVisibleChange = (visible) => {
      emits("options-visible-change", visible);
    };
    const onRemoveTag = (value, e) => {
      e.stopPropagation();
      const idx = valueList.value.indexOf(value);
      if (idx > -1) {
        valueList.value.splice(idx, 1);
        emitChange(valueList.value);
        emitUpdateValue(valueList.value);
      }
    };
    const onFoldTagClick = (e) => {
      if (foldTrigger === "click") {
        e.stopPropagation();
      }
    };
    const beforeTagPopoverShow = () => {
      if (isSelecting.value) {
        return false;
      }
      return true;
    };
    const onSelectClick = () => {
      if (isResponding.value) {
        if (!props.disabled) {
          isSelecting.value = true;
        }
      }
    };
    const onSelectDlgChange = (visible) => {
      onOptionVisibleChange(visible);
    };
    const onselectDlgCancelClick = () => {
      isSelecting.value = false;
      valueList.value = [...finalValueList.value];
    };
    const onselectDlgOkClick = () => {
      isSelecting.value = false;
      finalValueList.value = [...valueList.value];
      emitChange(valueList.value);
      emitUpdateValue(valueList.value);
    };
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock(
        "div",
        {
          ref_key: "selectRef",
          ref: selectRef,
          class: normalizeClass(["o-select", [
            `o-select-${color.value}`,
            `o-select-${props.variant}`,
            `o-select-${props.size || unref(defaultSize)}`,
            unref(round).class.value,
            {
              "is-selecting": isSelecting.value,
              "is-multiple": props.multiple && valueList.value.length > 0,
              "o-select-disabled": props.disabled,
              "o-select-clearable": isClearable.value,
              "o-select-is-loading": props.loading
            }
          ]]),
          style: normalizeStyle(unref(round).style.value),
          onClick: onSelectClick
        },
        [
          !props.multiple || props.multiple && valueList.value.length === 0 ? (openBlock(), createElementBlock("input", {
            key: 0,
            value: optionLabels.value[valueList.value[0]],
            type: "text",
            placeholder: props.placeholder,
            class: "o-select-input",
            readonly: ""
          }, null, 8, _hoisted_1)) : (openBlock(), createBlock(unref(OScroller), {
            key: 1,
            class: "o-select-tags-scroller",
            "wrap-class": "o-select-value-list",
            "show-type": "hover",
            size: "small",
            "disabled-x": ""
          }, {
            default: withCtx(() => [
              createElementVNode("div", _hoisted_2, [
                (openBlock(true), createElementBlock(
                  Fragment,
                  null,
                  renderList(valueListDisplay.value, (item) => {
                    return openBlock(), createElementBlock("div", {
                      key: item,
                      class: "o-select-tag"
                    }, [
                      createTextVNode(
                        toDisplayString(optionLabels.value[item]) + " ",
                        1
                        /* TEXT */
                      ),
                      createElementVNode("div", {
                        class: "o-select-tag-remove",
                        onClick: (e) => onRemoveTag(item, e)
                      }, [
                        createVNode(unref(IconClose))
                      ], 8, _hoisted_3)
                    ]);
                  }),
                  128
                  /* KEYED_FRAGMENT */
                )),
                _ctx.showFoldTags && valueListFold.value.length > 0 ? (openBlock(), createBlock(unref(OPopover), {
                  key: 0,
                  visible: tagPopoverVisible.value,
                  "onUpdate:visible": _cache[0] || (_cache[0] = ($event) => tagPopoverVisible.value = $event),
                  trigger: unref(foldTrigger),
                  class: "o-select-tag-popover",
                  position: "bottom",
                  "before-show": beforeTagPopoverShow
                }, {
                  target: withCtx(() => [
                    createElementVNode("div", {
                      class: "o-select-tag",
                      onClick: onFoldTagClick
                    }, [
                      renderSlot(_ctx.$slots, "tag-fold", {}, () => [
                        createTextVNode(
                          toDisplayString(foldLabel.value),
                          1
                          /* TEXT */
                        )
                      ])
                    ])
                  ]),
                  default: withCtx(() => [
                    createElementVNode("div", _hoisted_4, [
                      (openBlock(true), createElementBlock(
                        Fragment,
                        null,
                        renderList(valueListFold.value, (item) => {
                          return openBlock(), createElementBlock("div", {
                            key: item,
                            class: "o-select-tag"
                          }, [
                            createTextVNode(
                              toDisplayString(optionLabels.value[item]) + " ",
                              1
                              /* TEXT */
                            ),
                            createElementVNode("div", {
                              class: "o-select-tag-remove",
                              onClick: (e) => onRemoveTag(item, e)
                            }, [
                              createVNode(unref(IconClose))
                            ], 8, _hoisted_5)
                          ]);
                        }),
                        128
                        /* KEYED_FRAGMENT */
                      ))
                    ])
                  ]),
                  _: 3
                  /* FORWARDED */
                }, 8, ["visible", "trigger"])) : createCommentVNode("v-if", true)
              ])
            ]),
            _: 3
            /* FORWARDED */
          })),
          createElementVNode("div", _hoisted_6, [
            createElementVNode("div", _hoisted_7, [
              props.loading ? (openBlock(), createElementBlock("div", _hoisted_8, [
                createVNode(unref(IconLoading), { class: "o-rotating" })
              ])) : isClearable.value ? (openBlock(), createElementBlock("div", {
                key: 1,
                class: "o-select-clear",
                onClick: clearClick
              }, [
                createVNode(unref(IconClose), { class: "o-select-clear-icon" })
              ])) : createCommentVNode("v-if", true),
              createElementVNode(
                "div",
                {
                  class: normalizeClass(["o-select-arrow", { active: isSelecting.value }])
                },
                [
                  renderSlot(_ctx.$slots, "arrow", { active: isSelecting.value }, () => [
                    createVNode(unref(IconChevronDown))
                  ])
                ],
                2
                /* CLASS */
              )
            ]),
            renderSlot(_ctx.$slots, "suffix", { active: isSelecting.value })
          ]),
          createVNode(unref(ClientOnly), null, {
            default: withCtx(() => [
              (openBlock(), createBlock(Teleport, {
                to: optionsRef.value,
                disabled: !optionsRef.value
              }, [
                withDirectives(createElementVNode(
                  "div",
                  _hoisted_9,
                  [
                    renderSlot(_ctx.$slots, "default", {}, () => [
                      createElementVNode("div", _hoisted_10, [
                        renderSlot(_ctx.$slots, "empty", {}, () => [
                          createElementVNode(
                            "span",
                            null,
                            toDisplayString(unref(t)("common.empty")),
                            1
                            /* TEXT */
                          )
                        ])
                      ])
                    ])
                  ],
                  512
                  /* NEED_PATCH */
                ), [
                  [vShow, optionsRef.value]
                ])
              ], 8, ["to", "disabled"])),
              isResponding.value ? (openBlock(), createBlock(unref(ODialog), {
                key: 0,
                visible: isSelecting.value,
                "onUpdate:visible": _cache[1] || (_cache[1] = ($event) => isSelecting.value = $event),
                "before-show": props.beforeOptionsShow,
                "before-hide": props.beforeOptionsHide,
                "hide-close": "",
                class: normalizeClass(["o-select-dlg", {
                  "is-loading": props.loading
                }]),
                "mask-close": !props.multiple,
                size: "small",
                scrollbar: false,
                onChange: onSelectDlgChange
              }, createSlots({
                default: withCtx(() => [
                  createVNode(_sfc_main$1, {
                    size: props.size,
                    "wrap-class": props.optionWrapClass,
                    loading: props.loading,
                    class: "o-select-options-dlg",
                    "option-title": props.optionTitle,
                    multiple: props.multiple
                  }, createSlots({
                    "option-target": withCtx(() => [
                      createElementVNode(
                        "div",
                        {
                          ref_key: "optionsRef",
                          ref: optionsRef
                        },
                        null,
                        512
                        /* NEED_PATCH */
                      )
                    ]),
                    _: 2
                    /* DYNAMIC */
                  }, [
                    renderList(unref(filterSlots)(_ctx.$slots, unref(slot).option.names), (name) => {
                      return {
                        name,
                        fn: withCtx(() => [
                          renderSlot(_ctx.$slots, name)
                        ])
                      };
                    })
                  ]), 1032, ["size", "wrap-class", "loading", "option-title", "multiple"])
                ]),
                _: 2
                /* DYNAMIC */
              }, [
                props.optionTitle ? {
                  name: "header",
                  fn: withCtx(() => [
                    createElementVNode(
                      "div",
                      _hoisted_11,
                      toDisplayString(props.optionTitle),
                      1
                      /* TEXT */
                    )
                  ]),
                  key: "0"
                } : void 0,
                props.multiple ? {
                  name: "actions",
                  fn: withCtx(() => [
                    createVNode(unref(OButton), {
                      class: "o-dlg-btn",
                      variant: "text",
                      size: "large",
                      onClick: onselectDlgCancelClick
                    }, {
                      default: withCtx(() => [
                        createTextVNode(
                          toDisplayString(unref(t)("select.cancel")),
                          1
                          /* TEXT */
                        )
                      ]),
                      _: 1
                      /* STABLE */
                    }),
                    createVNode(unref(OButton), {
                      class: "o-dlg-btn",
                      variant: "text",
                      size: "large",
                      onClick: onselectDlgOkClick
                    }, {
                      default: withCtx(() => [
                        createTextVNode(
                          toDisplayString(unref(t)("select.confirm")),
                          1
                          /* TEXT */
                        )
                      ]),
                      _: 1
                      /* STABLE */
                    })
                  ]),
                  key: "1"
                } : void 0
              ]), 1032, ["visible", "before-show", "before-hide", "mask-close", "class"])) : (openBlock(), createElementBlock(
                Fragment,
                { key: 1 },
                [
                  !props.disabled ? (openBlock(), createBlock(unref(OPopup), {
                    key: 0,
                    visible: isSelecting.value,
                    "onUpdate:visible": _cache[2] || (_cache[2] = ($event) => isSelecting.value = $event),
                    "wrap-class": "o-options-popup",
                    transition: props.transition,
                    "unmount-on-hide": props.unmountOnHide,
                    position: props.optionPosition,
                    wrapper: props.optionsWrapper,
                    target: selectRef.value,
                    trigger: props.trigger,
                    offset: 4,
                    "adjust-min-width": props.optionWidthMode === "min-width",
                    "adjust-width": props.optionWidthMode === "width",
                    "before-show": props.beforeOptionsShow,
                    "before-hide": props.beforeOptionsHide,
                    onChange: onOptionVisibleChange
                  }, {
                    default: withCtx(() => [
                      createVNode(_sfc_main$1, {
                        size: props.size,
                        "wrap-class": props.optionWrapClass,
                        loading: props.loading,
                        multiple: props.multiple
                      }, createSlots({
                        "option-target": withCtx(() => [
                          createElementVNode(
                            "div",
                            {
                              ref_key: "optionsRef",
                              ref: optionsRef
                            },
                            null,
                            512
                            /* NEED_PATCH */
                          )
                        ]),
                        _: 2
                        /* DYNAMIC */
                      }, [
                        renderList(unref(filterSlots)(_ctx.$slots, unref(slot).option.names), (name) => {
                          return {
                            name,
                            fn: withCtx(() => [
                              renderSlot(_ctx.$slots, name)
                            ])
                          };
                        })
                      ]), 1032, ["size", "wrap-class", "loading", "multiple"])
                    ]),
                    _: 3
                    /* FORWARDED */
                  }, 8, ["visible", "transition", "unmount-on-hide", "position", "wrapper", "target", "trigger", "adjust-min-width", "adjust-width", "before-show", "before-hide"])) : createCommentVNode("v-if", true)
                ],
                64
                /* STABLE_FRAGMENT */
              ))
            ]),
            _: 3
            /* FORWARDED */
          })
        ],
        6
        /* CLASS, STYLE */
      );
    };
  }
});
export {
  _sfc_main as default
};
