<script setup lang="ts">
import { ref } from 'vue'
import { cn } from '@/lib/utils'
import { IconHeart, IconThumbUp } from '@tabler/icons-vue'
import SolarStarBold from '~icons/solar/star-bold'

export interface RatingProps {
  value: number
  max?: number
  icon?: 'star' | 'heart' | 'thumbsUp'
  size?: 'sm' | 'md' | 'lg'
  readOnly?: boolean
  class?: string
}

const props = withDefaults(defineProps<RatingProps>(), {
  max: 5,
  icon: 'star',
  size: 'md',
  readOnly: false,
})

const emit = defineEmits<{ change: [value: number] }>()

const hoverValue = ref<number | null>(null)

const iconMap = { star: SolarStarBold, heart: IconHeart, thumbsUp: IconThumbUp }
const sizeMap = { sm: 'babylai:w-4 babylai:h-4', md: 'babylai:w-7 babylai:h-7', lg: 'babylai:w-13 babylai:h-13' }

const IconComponent = iconMap[props.icon]
</script>

<template>
  <div :class="cn('babylai:inline-flex babylai:gap-2', props.class)">
    <component
      :is="IconComponent"
      v-for="i in max"
      :key="i"
      :class="cn(
        sizeMap[size],
        'babylai:cursor-pointer babylai:transition-colors',
        (hoverValue !== null ? hoverValue : value) >= i
          ? 'babylai:text-[#F49E00] babylai:fill-[#F49E00]'
          : 'babylai:text-gray-300',
        readOnly && 'babylai:cursor-default'
      )"
      :aria-hidden="readOnly"
      :role="readOnly ? undefined : 'button'"
      :tabindex="readOnly ? -1 : 0"
      :aria-label="`Rate ${i} out of ${max}`"
      @mouseenter="!readOnly && (hoverValue = i)"
      @mouseleave="!readOnly && (hoverValue = null)"
      @click="!readOnly && emit('change', i)"
    />
  </div>
</template>
