<template>
  <MBottomBar class="mc-stepper-bar" :fixed="fixed" :html-tag="htmlTag">
    <MButton
      size="s"
      theme="bordered-danger"
      :label="props.cancelButtonLabel"
      @click="(event) => $emit('cancel', event)"
    />
    <div class="mc-stepper-bar__actions">
      <MButton
        v-if="currentStep > 0"
        theme="bordered-neutral"
        size="s"
        :label="props.prevButtonLabel"
        @click="handlePrev()"
      />
      <MButton
        class="mc-stepper-bar__next"
        size="s"
        :disabled="!props.nextBtnEnabled"
        :label="
          currentStep < props.stepsNb
            ? props.nextButtonLabel
            : props.validateButtonLabel
        "
        @click="currentStep < props.stepsNb ? handleNext() : emit('validate')"
      />
    </div>
  </MBottomBar>
</template>

<script setup>
import { ref, watch } from 'vue';
import MBottomBar from '../bottombar/MBottomBar.vue';
import MButton from '../button/MButton.vue';

/** props */
const props = defineProps({
  /**
   * Number of steps in the process
   */
  stepsNb: {
    type: Number,
    required: true,
  },
  /**
   * Value of the current step. _(Can be used with a v-model)_
   */
  modelValue: {
    type: Number,
    default: undefined,
  },
  /**
   * Label for the button 'next'
   */
  nextButtonLabel: {
    type: String,
    default: 'Next',
  },
  /**
   * Label for the button 'previous'
   */
  prevButtonLabel: {
    type: String,
    default: 'Back',
  },
  /**
   * Label for the button 'cancel'
   */
  cancelButtonLabel: {
    type: String,
    default: 'Cancel',
  },
  /**
   * Label for the button 'validate'
   */
  validateButtonLabel: {
    type: String,
    default: 'Validate',
  },
  /**
   * Whether the next button should be enabled, this can be used to prevent user to click the 'next' or 'validate' button.
   */
  nextBtnEnabled: {
    type: Boolean,
    default: true,
  },
  /**
   * Apply a `position: fixed` to the component and position it at the bottom of the page
   */
  fixed: {
    type: Boolean,
    default: false,
  },
  /**
   * Allows to define the HTML tag to be used for the container element
   */
  htmlTag: {
    type: String,
    default: 'div',
  },
  /**
   * Allows to prevent step change by returning false.
   */
  beforeStepChange: {
    type: Function,
    default: () => true,
  },
});

/** emit */
const emit = defineEmits([
  'next-step',
  'previous-step',
  'update:modelValue',
  'cancel',
  'validate',
]);

/** data */
const currentStep = ref(0);

/** methods */
const handleNext = async () => {
  if (await props.beforeStepChange(currentStep.value + 1)) {
    currentStep.value++;
    emit('next-step', currentStep.value);
  }
};

const handlePrev = async () => {
  if (currentStep.value - 1 >= 0 && await props.beforeStepChange(currentStep.value - 1)) {
    currentStep.value--;
    emit('previous-step', currentStep.value);
  }
};

watch(
  () => props.modelValue,
  (value) => {
    if (value !== undefined) {
      currentStep.value = value;
    }
  },
  { immediate: true },
);

watch(
  () => currentStep.value,
  (value) => {
    emit('update:modelValue', value);
  },
);
</script>

<style lang="scss" scoped>
@import 'settings-tools/all-settings';

.mc-stepper-bar {
  $parent: get-parent-selector(&);

  justify-content: space-between;

  &__actions {
    align-items: center;
    display: flex;
    gap: $mu100;
  }
}
</style>
