<script lang="ts" setup>
import type { IconType } from '@bagelink/vue'
import { Icon } from '@bagelink/vue'

const { rating, totalStars = 5, iconType = 'star', fillColor = '#fabf05', emptyColor = 'lightgray', size = 1.4 } = defineProps<{
	rating: number | string
	totalStars?: number
	iconType?: IconType
	fillColor?: string
	emptyColor?: string
	size?: number
}>()

function getFillWidth(n: number): string {
	const ratingNumber = typeof rating === 'string' ? Number.parseFloat(rating.replace(',', '.')) : rating
	if (n <= Math.floor(ratingNumber)) {
		return '100%'
	} if (n > Math.ceil(ratingNumber)) {
		return '0%'
	} else {
		return `${(ratingNumber % 1) * 100}%`
	}
}
</script>

<template>
	<div class="rating">
		<template v-if="iconType === 'star'">
			<span
				v-for="n in totalStars" :key="n" class="star-icon p-025"
				:style="{ '--gradient-width': getFillWidth(n), '--fill-color': fillColor, '--empty-color': emptyColor }"
			>
				★
			</span>
		</template>
		<template v-else>
			<Icon
				v-for="n in totalStars" :key="n" fill :name="iconType" class="star-icon p-0" :size="size" :style="{
					'gap': `${size * 0.3}rem`,
					'--gradient-width': getFillWidth(n),
					'--fill-color': fillColor,
					'--empty-color': emptyColor,
				}"
			/>
		</template>
	</div>
</template>

<style scoped>
.rating {
	display: flex;
	align-items: center;
}

.star-icon {
	--gradient-width: 0%;
	--fill-color: #fabf05;
	--empty-color: lightgray;
	position: relative;
	display: inline-block;
	background: linear-gradient(to right, var(--fill-color) var(--gradient-width), var(--empty-color) 0%);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	fill: transparent;
}
</style>
