import { createComponent, computed, h, hSlot, watch, onMounted, onBeforeUnmount, hDir, isNumber, QBtn, hMergeSlot, getCurrentInstance } from './__federation_expose_Modules-a9c6a6fc.js';
import { usePanelChildProps, usePanelProps, usePanelEmits, usePanel } from './use-panel-471006fb.js';
import { useDarkProps, useDark } from './use-dark-b88930fe.js';
import { useFullscreenProps, useFullscreenEmits, useFullscreen } from './use-fullscreen-d7864fdb.js';

const QCarouselSlide = createComponent({
  name: 'QCarouselSlide',

  props: {
    ...usePanelChildProps,
    imgSrc: String
  },

  setup (props, { slots }) {
    const style = computed(() => (
      props.imgSrc
        ? { backgroundImage: `url("${ props.imgSrc }")` }
        : {}
    ));

    return () => h('div', {
      class: 'q-carousel__slide',
      style: style.value
    }, hSlot(slots.default))
  }
});

const navigationPositionOptions = [ 'top', 'right', 'bottom', 'left' ];
const controlTypeOptions = [ 'regular', 'flat', 'outline', 'push', 'unelevated' ];

const QCarousel = createComponent({
  name: 'QCarousel',

  props: {
    ...useDarkProps,
    ...usePanelProps,
    ...useFullscreenProps,

    transitionPrev: { // usePanelParentProps override
      type: String,
      default: 'fade'
    },
    transitionNext: { // usePanelParentProps override
      type: String,
      default: 'fade'
    },

    height: String,
    padding: Boolean,

    controlColor: String,
    controlTextColor: String,
    controlType: {
      type: String,
      validator: v => controlTypeOptions.includes(v),
      default: 'flat'
    },

    autoplay: [ Number, Boolean ],

    arrows: Boolean,
    prevIcon: String,
    nextIcon: String,

    navigation: Boolean,
    navigationPosition: {
      type: String,
      validator: v => navigationPositionOptions.includes(v)
    },
    navigationIcon: String,
    navigationActiveIcon: String,

    thumbnails: Boolean
  },

  emits: [
    ...useFullscreenEmits,
    ...usePanelEmits
  ],

  setup (props, { slots }) {
    const { proxy: { $q } } = getCurrentInstance();

    const isDark = useDark(props, $q);

    let timer = null, panelsLen;

    const {
      updatePanelsList, getPanelContent,
      panelDirectives, goToPanel,
      previousPanel, nextPanel, getEnabledPanels,
      panelIndex
    } = usePanel();

    const { inFullscreen } = useFullscreen();

    const style = computed(() => (
      inFullscreen.value !== true && props.height !== void 0
        ? { height: props.height }
        : {}
    ));

    const direction = computed(() => (props.vertical === true ? 'vertical' : 'horizontal'));

    const classes = computed(() =>
      `q-carousel q-panel-parent q-carousel--with${ props.padding === true ? '' : 'out' }-padding`
      + (inFullscreen.value === true ? ' fullscreen' : '')
      + (isDark.value === true ? ' q-carousel--dark q-dark' : '')
      + (props.arrows === true ? ` q-carousel--arrows-${ direction.value }` : '')
      + (props.navigation === true ? ` q-carousel--navigation-${ navigationPosition.value }` : '')
    );

    const arrowIcons = computed(() => {
      const ico = [
        props.prevIcon || $q.iconSet.carousel[ props.vertical === true ? 'up' : 'left' ],
        props.nextIcon || $q.iconSet.carousel[ props.vertical === true ? 'down' : 'right' ]
      ];

      return props.vertical === false && $q.lang.rtl === true
        ? ico.reverse()
        : ico
    });

    const navIcon = computed(() => props.navigationIcon || $q.iconSet.carousel.navigationIcon);
    const navActiveIcon = computed(() => props.navigationActiveIcon || navIcon.value);
    const navigationPosition = computed(() => props.navigationPosition
      || (props.vertical === true ? 'right' : 'bottom')
    );

    const controlProps = computed(() => ({
      color: props.controlColor,
      textColor: props.controlTextColor,
      round: true,
      [ props.controlType ]: true,
      dense: true
    }));

    watch(() => props.modelValue, () => {
      if (props.autoplay) {
        startTimer();
      }
    });

    watch(() => props.autoplay, val => {
      if (val) {
        startTimer();
      }
      else if (timer !== null) {
        clearTimeout(timer);
        timer = null;
      }
    });

    function startTimer () {
      const duration = isNumber(props.autoplay) === true
        ? Math.abs(props.autoplay)
        : 5000;

      timer !== null && clearTimeout(timer);
      timer = setTimeout(() => {
        timer = null;

        if (duration >= 0) {
          nextPanel();
        }
        else {
          previousPanel();
        }
      }, duration);
    }

    onMounted(() => {
      props.autoplay && startTimer();
    });

    onBeforeUnmount(() => {
      timer !== null && clearTimeout(timer);
    });

    function getNavigationContainer (type, mapping) {
      return h('div', {
        class: 'q-carousel__control q-carousel__navigation no-wrap absolute flex'
          + ` q-carousel__navigation--${ type } q-carousel__navigation--${ navigationPosition.value }`
          + (props.controlColor !== void 0 ? ` text-${ props.controlColor }` : '')
      }, [
        h('div', {
          class: 'q-carousel__navigation-inner flex flex-center no-wrap'
        }, getEnabledPanels().map(mapping))
      ])
    }

    function getContent () {
      const node = [];

      if (props.navigation === true) {
        const fn = slots[ 'navigation-icon' ] !== void 0
          ? slots[ 'navigation-icon' ]
          : opts => h(QBtn, {
            key: 'nav' + opts.name,
            class: `q-carousel__navigation-icon q-carousel__navigation-icon--${ opts.active === true ? '' : 'in' }active`,
            ...opts.btnProps,
            onClick: opts.onClick
          });

        const maxIndex = panelsLen - 1;
        node.push(
          getNavigationContainer('buttons', (panel, index) => {
            const name = panel.props.name;
            const active = panelIndex.value === index;

            return fn({
              index,
              maxIndex,
              name,
              active,
              btnProps: {
                icon: active === true ? navActiveIcon.value : navIcon.value,
                size: 'sm',
                ...controlProps.value
              },
              onClick: () => { goToPanel(name); }
            })
          })
        );
      }
      else if (props.thumbnails === true) {
        const color = props.controlColor !== void 0
          ? ` text-${ props.controlColor }`
          : '';

        node.push(getNavigationContainer('thumbnails', panel => {
          const slide = panel.props;

          return h('img', {
            key: 'tmb#' + slide.name,
            class: `q-carousel__thumbnail q-carousel__thumbnail--${ slide.name === props.modelValue ? '' : 'in' }active` + color,
            src: slide.imgSrc || slide[ 'img-src' ],
            onClick: () => { goToPanel(slide.name); }
          })
        }));
      }

      if (props.arrows === true && panelIndex.value >= 0) {
        if (props.infinite === true || panelIndex.value > 0) {
          node.push(
            h('div', {
              key: 'prev',
              class: `q-carousel__control q-carousel__arrow q-carousel__prev-arrow q-carousel__prev-arrow--${ direction.value } absolute flex flex-center`
            }, [
              h(QBtn, {
                icon: arrowIcons.value[ 0 ],
                ...controlProps.value,
                onClick: previousPanel
              })
            ])
          );
        }

        if (props.infinite === true || panelIndex.value < panelsLen - 1) {
          node.push(
            h('div', {
              key: 'next',
              class: 'q-carousel__control q-carousel__arrow q-carousel__next-arrow'
                + ` q-carousel__next-arrow--${ direction.value } absolute flex flex-center`
            }, [
              h(QBtn, {
                icon: arrowIcons.value[ 1 ],
                ...controlProps.value,
                onClick: nextPanel
              })
            ])
          );
        }
      }

      return hMergeSlot(slots.control, node)
    }

    return () => {
      panelsLen = updatePanelsList(slots);

      return h('div', {
        class: classes.value,
        style: style.value
      }, [
        hDir(
          'div',
          { class: 'q-carousel__slides-container' },
          getPanelContent(),
          'sl-cont',
          props.swipeable,
          () => panelDirectives.value
        )
      ].concat(getContent()))
    }
  }
});

export { QCarousel, QCarouselSlide };
