"use client"

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

interface StarRatingProps {
  value: number
  onChange?: (value: number) => void
  size?: "sm" | "md" | "lg"
  readOnly?: boolean
  className?: string
}

const sizeClasses = {
  sm: "h-4 w-4",
  md: "h-6 w-6",
  lg: "h-8 w-8",
}

const gapClasses = {
  sm: "gap-0.5",
  md: "gap-1",
  lg: "gap-1.5",
}

export function StarRating({
  value,
  onChange,
  size = "md",
  readOnly = false,
  className,
}: StarRatingProps) {
  const [hoverValue, setHoverValue] = useState(0)
  const [, setIsFocused] = useState(false)

  const handleClick = useCallback(
    (starValue: number) => {
      if (!readOnly && onChange) {
        onChange(starValue)
      }
    },
    [readOnly, onChange]
  )

  const handleKeyDown = useCallback(
    (e: React.KeyboardEvent) => {
      if (readOnly || !onChange) return

      switch (e.key) {
        case "ArrowRight":
        case "ArrowUp":
          e.preventDefault()
          onChange(Math.min(5, value + 1))
          break
        case "ArrowLeft":
        case "ArrowDown":
          e.preventDefault()
          onChange(Math.max(1, value - 1))
          break
        case "Home":
          e.preventDefault()
          onChange(1)
          break
        case "End":
          e.preventDefault()
          onChange(5)
          break
      }
    },
    [readOnly, onChange, value]
  )

  const displayValue = hoverValue || value

  return (
    <div
      className={cn("inline-flex items-center", gapClasses[size], className)}
      role="radiogroup"
      aria-label="Star rating"
      onMouseLeave={() => !readOnly && setHoverValue(0)}
      onKeyDown={handleKeyDown}
    >
      {Array.from({ length: 5 }, (_, i) => {
        const starValue = i + 1
        const isFilled = starValue <= displayValue
        const isInteractive = !readOnly && !!onChange

        return (
          <button
            key={starValue}
            type="button"
            role="radio"
            aria-checked={starValue === value}
            aria-label={`${starValue} star${starValue !== 1 ? "s" : ""}`}
            tabIndex={isInteractive ? (starValue === value || (value === 0 && starValue === 1) ? 0 : -1) : -1}
            disabled={readOnly}
            className={cn(
              "transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 rounded-sm",
              isInteractive && "cursor-pointer hover:scale-110 transition-transform",
              readOnly && "cursor-default"
            )}
            onClick={() => handleClick(starValue)}
            onMouseEnter={() => isInteractive && setHoverValue(starValue)}
            onFocus={() => setIsFocused(true)}
            onBlur={() => setIsFocused(false)}
          >
            <Star
              className={cn(
                sizeClasses[size],
                "transition-colors",
                isFilled
                  ? "fill-primary text-primary"
                  : "fill-none text-muted-foreground/40"
              )}
            />
          </button>
        )
      })}
    </div>
  )
}
