<template>
  <div :id="progressId" :class="['pkt-progressbar__container', className]" :style="containerStyles">
    <p v-if="title" :id="`${progressId}-title`" :class="titleClasses">
      {{ title }}
    </p>
    <div
      :role="role"
      class="pkt-progressbar__bar-wrapper"
      :aria-valuemin="valueMin"
      :aria-valuemax="valueMax"
      :aria-valuenow="valueCurrent"
      :aria-labelledby="computedAriaLabelledby"
      :aria-label="ariaLabel"
      :aria-valuetext="ariaValueText"
    >
      <div :class="barClasses"></div>
    </div>
    <div v-if="hasStatus" :class="statusClasses">
      <span :class="placementClasses" ref="labelRef">
        {{ statusType === 'percentage' ? `${currentPercentage}%` : formattedTitle }}
      </span>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, watch } from 'vue'
import { v4 as uuidv4 } from 'uuid'

const props = defineProps({
  valueCurrent: {
    type: Number,
    required: true,
  },
  valueMax: {
    type: Number,
    default: 100,
  },
  valueMin: {
    type: Number,
    default: 0,
  },
  skin: {
    type: String,
    default: 'dark-blue',
    validator: (value) => ['dark-blue', 'light-blue', 'green', 'red'].includes(value),
  },
  title: {
    type: String,
  },
  titlePosition: {
    type: String,
    default: 'left',
    validator: (value) => ['left', 'center'].includes(value),
  },
  statusType: {
    type: String,
    default: 'none',
    validator: (value) => ['none', 'percentage', 'fraction'].includes(value),
  },
  statusPlacement: {
    type: String,
    default: 'following',
    validator: (value) => ['center', 'left', 'following'].includes(value),
  },
  id: {
    type: String,
  },
  ariaLabel: {
    type: String,
  },
  ariaLabelledby: {
    type: String,
  },
  ariaValueText: {
    type: String,
  },
  role: {
    type: String,
    default: 'progressbar',
    validator: (value) => ['progressbar', 'meter'].includes(value),
  },
  className: {
    type: String,
  },
})

const labelRef = ref(null)
const labelWidth = ref(0)

onMounted(() => {
  if (labelRef.value) {
    labelWidth.value = labelRef.value.getBoundingClientRect().width
  }
})

watch(
  () => props.valueCurrent,
  (newVal, oldVal) => {
    if (newVal !== oldVal && labelRef.value) {
      labelWidth.value = labelRef.value.getBoundingClientRect().width
    }
  },
)

const totalSteps = computed(() => props.valueMax - props.valueMin)
const percentageOfSteps = computed(() => (props.valueCurrent / totalSteps.value) * 100)
const currentPercentage = computed(() =>
  props.valueMax !== 100 || props.valueMin !== 0 ? Math.round(percentageOfSteps.value) : props.valueCurrent,
)
const formattedTitle = computed(() => `${props.valueCurrent} av ${props.valueMax}`)
const hasStatus = computed(() => props.statusType !== 'none' && props.role === 'progressbar')
const progressId = computed(() => props.id || uuidv4())
const computedAriaLabelledby = computed(() => {
  return props.ariaLabelledby || (props.title && `${progressId.value}-title`)
})

const barClasses = computed(() => `pkt-progressbar__bar pkt-progressbar__bar--${props.skin}`)
const titleClasses = computed(() => ({
  'pkt-progressbar__title': true,
  'pkt-progressbar__title-center': props.titlePosition === 'center',
}))
const statusClasses = computed(() => ({
  'pkt-progressbar__status': true,
  'pkt-progressbar__status--center': props.statusPlacement === 'center',
}))
const placementClasses = computed(() => ({
  'pkt-progressbar__status-placement--following': props.statusPlacement === 'following',
  'pkt-progressbar__status-placement--center': props.statusPlacement === 'center',
  'pkt-progressbar__status-placement--left': props.statusPlacement === 'left',
}))

const containerStyles = computed(() => ({
  '--pkt-progress-label-width': `${labelWidth.value}px`,
  '--pkt-progress-width': `${currentPercentage.value}%`,
}))
</script>
