<script lang="ts">
	interface Props {
		rating: number;        // current user rating 0–5 (0 = unrated)
		avg?: number;          // average rating
		count?: number;        // total ratings
		readonly?: boolean;    // display-only mode
		size?: 'sm' | 'md';
		onrate?: (r: number) => void;
	}

	let { rating = 0, avg = 0, count = 0, readonly = false, size = 'md', onrate }: Props = $props();

	let hovered = $state(0);

	const starSize = $derived(size === 'sm' ? 'w-3.5 h-3.5' : 'w-5 h-5');
	const display = $derived(hovered || rating || 0);
</script>

<div class="flex items-center gap-1">
	<div class="flex items-center gap-0.5">
		{#each [1,2,3,4,5] as star}
			<button
				type="button"
				disabled={readonly}
				onmouseenter={() => { if (!readonly) hovered = star; }}
				onmouseleave={() => { if (!readonly) hovered = 0; }}
				onclick={() => { if (!readonly) onrate?.(star); }}
				class="transition-transform {readonly ? 'cursor-default' : 'cursor-pointer hover:scale-110 active:scale-95'} disabled:pointer-events-none"
				aria-label="Rate {star} star{star !== 1 ? 's' : ''}"
			>
				<svg
					class="{starSize} transition-colors"
					fill={star <= display ? 'currentColor' : 'none'}
					stroke="currentColor"
					stroke-width="1.5"
					viewBox="0 0 24 24"
				>
					<path
						stroke-linecap="round"
						stroke-linejoin="round"
						d="M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z"
					/>
				</svg>
			</button>
		{/each}
	</div>
	{#if avg && count}
		<span class="text-xs text-(--color-muted) ml-1">{avg} ({count})</span>
	{:else if avg}
		<span class="text-xs text-(--color-muted) ml-1">{avg}</span>
	{/if}
</div>

<style>
	button[disabled] { pointer-events: none; }
	svg { color: #f59e0b; }
</style>
