import { createVNode as _createVNode, createElementVNode as _createElementVNode, normalizeClass as _normalizeClass, normalizeStyle as _normalizeStyle, withDirectives as _withDirectives } from "vue";
// Styles
import "./VWindow.css";

// Components
import { VBtn } from "../VBtn/index.js"; // Composables
import { makeComponentProps } from "../../composables/component.js";
import { useGroup } from "../../composables/group.js";
import { useLocale, useRtl } from "../../composables/locale.js";
import { makeTagProps } from "../../composables/tag.js";
import { makeThemeProps, provideTheme } from "../../composables/theme.js"; // Directives
import vTouch from "../../directives/touch/index.js"; // Utilities
import { computed, nextTick, provide, ref, shallowRef, toRef, watch } from 'vue';
import { convertToUnit, genericComponent, IN_BROWSER, PREFERS_REDUCED_MOTION, propsFactory, useRender } from "../../util/index.js";
import { getScrollParent } from "../../util/getScrollParent.js"; // Types
export const VWindowSymbol = Symbol.for('vuetify:v-window');
export const VWindowGroupSymbol = Symbol.for('vuetify:v-window-group');
export const makeVWindowProps = propsFactory({
  continuous: Boolean,
  nextIcon: {
    type: [Boolean, String, Function, Object],
    default: '$next'
  },
  prevIcon: {
    type: [Boolean, String, Function, Object],
    default: '$prev'
  },
  reverse: Boolean,
  showArrows: {
    type: [Boolean, String],
    validator: v => typeof v === 'boolean' || v === 'hover'
  },
  verticalArrows: [Boolean, String],
  touch: {
    type: [Object, Boolean],
    default: undefined
  },
  direction: {
    type: String,
    default: 'horizontal'
  },
  modelValue: null,
  disabled: Boolean,
  selectedClass: {
    type: String,
    default: 'v-window-item--active'
  },
  // TODO: mandatory should probably not be exposed but do this for now
  mandatory: {
    type: [Boolean, String],
    default: 'force'
  },
  crossfade: Boolean,
  transitionDuration: Number,
  ...makeComponentProps(),
  ...makeTagProps(),
  ...makeThemeProps()
}, 'VWindow');
export const VWindow = genericComponent()({
  name: 'VWindow',
  directives: {
    vTouch
  },
  props: makeVWindowProps(),
  emits: {
    'update:modelValue': value => true
  },
  setup(props, {
    slots
  }) {
    const {
      themeClasses
    } = provideTheme(props);
    const {
      isRtl
    } = useRtl();
    const {
      t
    } = useLocale();
    const group = useGroup(props, VWindowGroupSymbol);
    const rootRef = ref();
    const isRtlReverse = computed(() => isRtl.value ? !props.reverse : props.reverse);
    const isReversed = shallowRef(false);
    const transition = computed(() => {
      if (props.crossfade) {
        return 'v-window-crossfade-transition';
      }
      const axis = props.direction === 'vertical' ? 'y' : 'x';
      const reverse = isRtlReverse.value ? !isReversed.value : isReversed.value;
      const direction = reverse ? '-reverse' : '';
      return `v-window-${axis}${direction}-transition`;
    });
    const transitionCount = shallowRef(0);
    const transitionHeight = ref(undefined);
    const activeIndex = computed(() => {
      return group.items.value.findIndex(item => group.selected.value.includes(item.id));
    });

    // Fix for https://github.com/vuetifyjs/vuetify/issues/18447
    watch(activeIndex, (newVal, oldVal) => {
      let scrollableParent;
      const savedScrollPosition = {
        left: 0,
        top: 0
      };
      if (IN_BROWSER && oldVal >= 0) {
        scrollableParent = getScrollParent(rootRef.value);
        savedScrollPosition.left = scrollableParent?.scrollLeft;
        savedScrollPosition.top = scrollableParent?.scrollTop;
      }
      const itemsLength = group.items.value.length;
      const lastIndex = itemsLength - 1;
      if (itemsLength <= 2) {
        isReversed.value = newVal < oldVal;
      } else if (newVal === lastIndex && oldVal === 0) {
        isReversed.value = false;
      } else if (newVal === 0 && oldVal === lastIndex) {
        isReversed.value = true;
      } else {
        isReversed.value = newVal < oldVal;
      }
      nextTick(() => {
        if (!IN_BROWSER || !scrollableParent) return;
        const currentScrollY = scrollableParent.scrollTop;
        if (currentScrollY !== savedScrollPosition.top) {
          scrollableParent.scrollTo({
            ...savedScrollPosition,
            behavior: 'instant'
          });
        }
        requestAnimationFrame(() => {
          if (!scrollableParent) return;
          const rafScrollY = scrollableParent.scrollTop;
          if (rafScrollY !== savedScrollPosition.top) {
            scrollableParent.scrollTo({
              ...savedScrollPosition,
              behavior: 'instant'
            });
          }
        });
      });
    }, {
      flush: 'sync'
    }); // Run synchronously before DOM updates

    provide(VWindowSymbol, {
      transition,
      isReversed,
      transitionCount,
      transitionHeight,
      rootRef
    });
    const canMoveBack = toRef(() => props.continuous || activeIndex.value !== 0);
    const canMoveForward = toRef(() => props.continuous || activeIndex.value !== group.items.value.length - 1);
    function prev() {
      canMoveBack.value && group.prev();
    }
    function next() {
      canMoveForward.value && group.next();
    }
    const arrows = computed(() => {
      const arrows = [];
      const prevProps = {
        icon: isRtl.value ? props.nextIcon : props.prevIcon,
        class: `v-window__${isRtlReverse.value ? 'right' : 'left'}`,
        onClick: group.prev,
        'aria-label': t('$vuetify.carousel.prev')
      };
      arrows.push(canMoveBack.value ? slots.prev ? slots.prev({
        props: prevProps
      }) : _createVNode(VBtn, prevProps, null) : _createElementVNode("div", null, null));
      const nextProps = {
        icon: isRtl.value ? props.prevIcon : props.nextIcon,
        class: `v-window__${isRtlReverse.value ? 'left' : 'right'}`,
        onClick: group.next,
        'aria-label': t('$vuetify.carousel.next')
      };
      arrows.push(canMoveForward.value ? slots.next ? slots.next({
        props: nextProps
      }) : _createVNode(VBtn, nextProps, null) : _createElementVNode("div", null, null));
      return arrows;
    });
    const touchOptions = computed(() => {
      if (props.touch === false) return props.touch;
      const options = {
        left: () => {
          isRtlReverse.value ? prev() : next();
        },
        right: () => {
          isRtlReverse.value ? next() : prev();
        },
        start: ({
          originalEvent
        }) => {
          originalEvent.stopPropagation();
        }
      };
      return {
        ...options,
        ...(props.touch === true ? {} : props.touch)
      };
    });
    function onKeyDown(e) {
      if (props.direction === 'horizontal' && e.key === 'ArrowLeft' || props.direction === 'vertical' && e.key === 'ArrowUp') {
        e.preventDefault();
        prev();
        nextTick(() => {
          canMoveBack.value ? focusArrow(0) : focusArrow(1);
        });
      }
      if (props.direction === 'horizontal' && e.key === 'ArrowRight' || props.direction === 'vertical' && e.key === 'ArrowDown') {
        e.preventDefault();
        next();
        nextTick(() => {
          canMoveForward.value ? focusArrow(1) : focusArrow(0);
        });
      }
    }
    function focusArrow(index) {
      const arrow = arrows.value[index];
      if (!arrow) return;
      const arrowEl = Array.isArray(arrow) ? arrow[0] : arrow;
      arrowEl.el?.focus();
    }
    useRender(() => _withDirectives(_createVNode(props.tag, {
      "ref": rootRef,
      "class": _normalizeClass(['v-window', {
        'v-window--show-arrows-on-hover': props.showArrows === 'hover',
        'v-window--vertical-arrows': !!props.verticalArrows,
        'v-window--crossfade': !!props.crossfade
      }, themeClasses.value, props.class]),
      "style": _normalizeStyle([props.style, {
        '--v-window-transition-duration': !PREFERS_REDUCED_MOTION() ? convertToUnit(props.transitionDuration, 'ms') : null
      }])
    }, {
      default: () => [_createElementVNode("div", {
        "class": "v-window__container",
        "style": {
          height: transitionHeight.value
        }
      }, [slots.default?.({
        group
      }), props.showArrows !== false && _createElementVNode("div", {
        "class": _normalizeClass(['v-window__controls', {
          'v-window__controls--left': props.verticalArrows === 'left' || props.verticalArrows === true
        }, {
          'v-window__controls--right': props.verticalArrows === 'right'
        }]),
        "onKeydown": onKeyDown
      }, [arrows.value])]), slots.additional?.({
        group
      })]
    }), [[vTouch, touchOptions.value]]));
    return {
      group
    };
  }
});
//# sourceMappingURL=VWindow.js.map