"use client"

import { useState, useRef } from "react"
import { Star } from "lucide-react"
import { cn } from "@/lib/utils"

interface RatingProps {
    value: number
    onChange?: (value: number) => void
    readonly?: boolean
    className?: string
    size?: "sm" | "md" | "lg"
    precision?: "full" | "half" | "decimal"
}

export function StarRating({
    value,
    onChange,
    readonly = false,
    className,
    size = "md",
    precision = "decimal"
}: RatingProps) {
    const [hoverValue, setHoverValue] = useState<number | null>(null)
    const containerRef = useRef<HTMLDivElement>(null)

    const stars = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    const starSize = {
        sm: "h-3 w-3",
        md: "h-4 w-4",
        lg: "h-5 w-5"
    }[size]

    const handleMouseMove = (e: React.MouseEvent, starIndex: number) => {
        if (readonly) return

        const rect = e.currentTarget.getBoundingClientRect()
        const x = e.clientX - rect.left
        const width = rect.width
        const fraction = x / width

        let newValue: number
        if (precision === "decimal") {
            // Allow 0.1 precision (e.g., 9.2)
            newValue = starIndex + Math.round(fraction * 10) / 10
            newValue = Math.max(starIndex, Math.min(starIndex + 1, newValue))
        } else if (precision === "half") {
            // Half-star precision
            newValue = fraction < 0.5 ? starIndex + 0.5 : starIndex + 1
        } else {
            // Full star only
            newValue = starIndex + 1
        }

        setHoverValue(newValue)
    }

    const handleClick = () => {
        if (!readonly && hoverValue !== null && onChange) {
            // Round to 1 decimal place
            onChange(Math.round(hoverValue * 10) / 10)
        }
    }

    const displayValue = hoverValue !== null ? hoverValue : value

    // Calculate fill percentage for each star
    const getStarFill = (starIndex: number): number => {
        const starStart = starIndex
        const starEnd = starIndex + 1

        if (displayValue >= starEnd) return 100
        if (displayValue <= starStart) return 0
        return (displayValue - starStart) * 100
    }

    return (
        <div
            ref={containerRef}
            className={cn("flex gap-0.5 items-center", className)}
            onMouseLeave={() => !readonly && setHoverValue(null)}
        >
            {stars.map((star, index) => {
                const fillPercent = getStarFill(index)

                return (
                    <button
                        key={star}
                        type="button"
                        disabled={readonly}
                        className={cn(
                            "p-0.5 transition-transform relative",
                            readonly ? "cursor-default" : "cursor-pointer hover:scale-110"
                        )}
                        onMouseMove={(e) => handleMouseMove(e, index)}
                        onClick={handleClick}
                    >
                        {/* Background star (empty) */}
                        <Star
                            className={cn(starSize, "fill-muted text-muted-foreground")}
                        />
                        {/* Foreground star (filled) - uses clip-path for partial fill */}
                        <div
                            className="absolute inset-0 p-0.5 overflow-hidden"
                            style={{
                                clipPath: `inset(0 ${100 - fillPercent}% 0 0)`
                            }}
                        >
                            <Star
                                className={cn(starSize, "fill-primary text-primary")}
                            />
                        </div>
                    </button>
                )
            })}

            {/* Display numeric value */}
            {!readonly && (
                <span className="ml-2 text-sm font-mono text-muted-foreground min-w-[2.5rem]">
                    {displayValue > 0 ? displayValue.toFixed(1) : "—"}
                </span>
            )}
        </div>
    )
}
