<script setup>
import { computed, ref } from "vue";
import Step from "primevue/step";
import StepList from "primevue/steplist";
import Stepper from "primevue/stepper";

const props = defineProps({
  modelValue: { type: Number, default: 0 },
  steps: {
    type: Array,
    default: () => [],
  },
  ariaLabel: {
    type: String,
    default: "Stappen",
  },
  clickable: {
    type: Boolean,
    default: false,
  },
  allowForwardJump: {
    type: Boolean,
    default: false,
  },
  /**
   * When set (array of booleans, same order as `steps`), “passed” styling and primary connectors
   * follow validation, not step index. Omitted or null keeps legacy behaviour (index before current).
   */
  stepComplete: {
    type: Array,
    default: null,
  },
  class: {
    type: [String, Object, Array],
    default: "",
  },
});

const emit = defineEmits(["update:modelValue", "step-click"]);

/** Remount Stepper when a click is rejected so PrimeVue internal d_value matches parent again. */
const stepperResetKey = ref(0);

const normalizedValue = computed(() => String((props.modelValue ?? 0) + 1));
const currentIndex = computed(() => Number(props.modelValue ?? 0));

function isPassedByIndex(index) {
  return index < currentIndex.value;
}

function isActive(index) {
  return index === currentIndex.value;
}

function isTrailComplete(index) {
  const sc = props.stepComplete;
  if (sc != null && Array.isArray(sc)) {
    return index < sc.length ? !!sc[index] : false;
  }
  return isPassedByIndex(index);
}

/** One visual state per step: active → outline; trail complete → filled primary; else muted. */
function stepProgressClass(index) {
  if (isActive(index)) return "base-stepper__step--active";
  if (isTrailComplete(index)) return "base-stepper__step--passed";
  return "base-stepper__step--upcoming";
}

/**
 * PrimeVue Step calls $pcStepper.updateValue() on the inner button; @click on <Step> does not
 * reach that button (inheritAttrs: false). Sync parent v-model from Stepper's update:value instead.
 */
function onStepperValueUpdate(raw) {
  const index = Number(raw) - 1;
  if (!Number.isFinite(index)) {
    return;
  }
  if (!props.clickable) {
    stepperResetKey.value += 1;
    return;
  }
  if (!props.allowForwardJump && index > currentIndex.value) {
    stepperResetKey.value += 1;
    return;
  }
  emit("step-click", index);
  emit("update:modelValue", index);
}
</script>

<template>
  <Stepper
    :key="stepperResetKey"
    :value="normalizedValue"
    :linear="!clickable"
    :class="[props.class, !clickable && 'base-stepper--readonly']"
    @update:value="onStepperValueUpdate"
  >
    <StepList :aria-label="ariaLabel">
      <Step
        v-for="(step, idx) in steps"
        :key="step?.key ?? step?.label ?? idx"
        :value="String(idx + 1)"
        :class="stepProgressClass(idx)"
      >
        {{ step?.label ?? `Stap ${idx + 1}` }}
      </Step>
    </StepList>
  </Stepper>
</template>
