<template>
  <view
    :class="dropdownItemClass"
    :style="dropdownItemStyle"
    :id="itemId"
    @click="onItemClick"
  >
    <view v-if="label" :class="bem.e('label')">
      {{ label }}
      <text v-if="(!isNullish(title) || !isNullish(innerValue)) && separator">
        {{ separator }}
      </text>
    </view>
    <view v-if="title" :class="bem.e('title')">
      {{ title }}
    </view>
    <view v-if="!isNullish(innerValue)" :class="bem.e('value')">
      {{ currentLabel }}
    </view>
    <view v-else-if="placeholder" :class="bem.e('placeholder')">
      {{ placeholder }}
    </view>
    <view :class="bem.e('arrow')">
      <sar-icon :name="currentArrow" />
    </view>
  </view>

  <view
    v-if="wholeVisible"
    :class="bem.e('away')"
    :style="awayInset"
    @click="onAwayClick"
    @touchmove.stop.prevent
  />
  <view v-if="wholeVisible" :class="bem.e('popover')" :style="popupInset">
    <sar-popup
      :root-class="bem.e('popup')"
      :root-style="
        stringifyStyle({
          position: 'absolute',
        })
      "
      :overlay-style="stringifyStyle({ position: 'absolute' })"
      :overlay-class="bem.e('overlay')"
      :effect="popupEffect"
      :visible="popupVisible"
      :duration="context.duration"
      @after-leave="onAfterLeave"
      @overlay-click="onOverlayClick"
    >
      <slot>
        <sar-list inlaid>
          <sar-list-item
            v-for="(item, i) in options"
            :key="i"
            :title="item.label"
            hover
            :root-class="
              classNames(
                bem.e('option'),
                bem.em('option', 'active', item.value === innerValue),
              )
            "
            @click="onOptionClick(item)"
          >
            <template #arrow>
              <view :class="bem.e('option-icon')">
                <sar-icon name="success" />
              </view>
            </template>
          </sar-list-item>
        </sar-list>
      </slot>
    </sar-popup>
  </view>
</template>

<script lang="ts">
import { defineComponent as _defineComponent } from "vue";
import {
  computed,
  getCurrentInstance,
  ref,
  watch,
  inject,
  onMounted,
  onUnmounted
} from "vue";
import {
  classNames,
  stringifyStyle,
  createBem,
  uniqid,
  getBoundingClientRect,
  getViewportSize,
  isNullish
} from "../utils";
import SarPopup from "../popup/popup.vue";
import SarList from "../list/list.vue";
import SarListItem from "../list-item/list-item.vue";
import SarIcon from "../icon/icon.vue";
import {
  dropdownContextSymbol,
  dropdownItemProps
} from "../dropdown/common";
const __default__ = {
  options: {
    virtualHost: true,
    styleIsolation: "shared"
  }
};
export default /* @__PURE__ */ _defineComponent({
  ...__default__,
  __name: "dropdown-item",
  props: dropdownItemProps,
  emits: ["update:model-value", "update:visible"],
  setup(__props, { expose: __expose, emit: __emit }) {
    __expose();
    const props = __props;
    const emit = __emit;
    const bem = createBem("dropdown-item");
    const context = inject(
      dropdownContextSymbol
    );
    if (!context) {
      throw new Error("DropdownItem must be included in Dropdown.");
    }
    const itemId = uniqid();
    const instance = getCurrentInstance();
    const innerValue = ref(props.modelValue);
    watch(
      () => props.modelValue,
      () => {
        innerValue.value = props.modelValue;
      }
    );
    const innerVisible = ref(props.visible);
    const wholeVisible = ref(props.visible);
    const popupVisible = ref(props.visible);
    watch(
      () => props.visible,
      () => {
        innerVisible.value = props.visible;
      }
    );
    watch(innerVisible, () => {
      if (innerVisible.value) {
        wholeVisible.value = true;
        context.hideOthers(instance);
        setPosition().then(() => {
          popupVisible.value = true;
        });
      } else {
        popupVisible.value = false;
      }
    });
    const popupInset = ref("");
    const awayInset = ref("");
    const setPosition = async () => {
      const viewportSize = await getViewportSize();
      const itemRect = await getBoundingClientRect(`#${itemId}`, instance);
      const nextPopupInset = {
        left: 0,
        right: 0,
        top: 0,
        bottom: 0
      };
      const nextAwayInset = {
        left: 0,
        right: 0,
        top: 0,
        bottom: 0
      };
      if (context.direction === "down") {
        nextPopupInset.top = `calc(${itemRect.bottom}px + var(--window-top))`;
        nextPopupInset.bottom = 0;
        nextAwayInset.top = 0;
        nextAwayInset.bottom = `calc(${viewportSize.height - itemRect.bottom}px + var(--window-top))`;
      } else {
        nextPopupInset.top = 0;
        nextPopupInset.bottom = `${viewportSize.height - itemRect.top}px`;
        nextAwayInset.top = `calc(${itemRect.bottom}px + var(--window-top))`;
        nextAwayInset.bottom = 0;
      }
      popupInset.value = stringifyStyle(nextPopupInset);
      awayInset.value = stringifyStyle(nextAwayInset);
    };
    const setInnerVisible = (visible) => {
      if (visible !== innerVisible.value) {
        innerVisible.value = visible;
        emit("update:visible", visible);
      }
    };
    const onItemClick = () => {
      if (!context.disabled && !props.disabled) {
        setInnerVisible(!innerVisible.value);
      }
    };
    const onOptionClick = (item) => {
      if (item.value !== innerValue.value) {
        innerValue.value = item.value;
      }
      setInnerVisible(false);
    };
    const onOverlayClick = () => {
      if (context.overlayClosable) {
        setInnerVisible(false);
      }
    };
    const onAwayClick = () => {
      if (context.awayClosable) {
        setInnerVisible(false);
      }
    };
    const onAfterLeave = () => {
      wholeVisible.value = false;
    };
    const hide = () => {
      setInnerVisible(false);
    };
    onMounted(() => {
      context.register(instance, {
        hide,
        visible: wholeVisible
      });
    });
    onUnmounted(() => {
      context.unregister(instance);
    });
    const currentLabel = computed(() => {
      return props.options?.find((option) => option.value === innerValue.value)?.label;
    });
    const currentArrow = computed(() => {
      return wholeVisible.value ? "caret-up" : "caret-down";
    });
    const popupEffect = computed(() => {
      return context.direction === "up" ? "slide-bottom" : "slide-top";
    });
    const dropdownItemClass = computed(() => {
      return classNames(
        bem.b(),
        bem.m(context.direction),
        bem.m("show", wholeVisible.value),
        bem.m("disabled", context.disabled || props.disabled),
        props.rootClass
      );
    });
    const dropdownItemStyle = computed(() => {
      return stringifyStyle(props.rootStyle);
    });
    const __returned__ = { props, emit, bem, context, itemId, instance, innerValue, innerVisible, wholeVisible, popupVisible, popupInset, awayInset, setPosition, setInnerVisible, onItemClick, onOptionClick, onOverlayClick, onAwayClick, onAfterLeave, hide, currentLabel, currentArrow, popupEffect, dropdownItemClass, dropdownItemStyle, get classNames() {
      return classNames;
    }, get stringifyStyle() {
      return stringifyStyle;
    }, get isNullish() {
      return isNullish;
    }, SarPopup, SarList, SarListItem, SarIcon };
    return __returned__;
  }
});
</script>

<style lang="scss">
@use './index.scss';
</style>