'use client';
import { FunctionComponent } from 'react';
import { useLocale } from 'next-intl';
import Box from '@mui/material/Box';
import IconButton from '@mui/material/IconButton';
import { AppIcon } from '@/components/common';

export interface RatingInputProps {
  /** Current rating, 0–max (0 = none chosen). Read-only display accepts a fraction (e.g. 4.5) and renders
   * a partially-filled star; interactive selection is always a whole star. */
  value: number;
  /** Called with the clicked star value. Omit (or set `readOnly`) for a display-only star row. */
  onChange?: (value: number) => void;
  /** Non-interactive display (e.g. a review card). */
  readOnly?: boolean;
  /** Number of stars (default 5). */
  max?: number;
  /** Icon size in px (default 28 interactive / caller-set for display). */
  size?: number;
  /** Accessible name for the whole control — translated by the caller. */
  ariaLabel?: string;
}

const DEFAULT_MAX = 5;
const DEFAULT_SIZE = 28;

/**
 * The 1–max star input/display. Interactive when an `onChange` is passed and not `readOnly` (each star is
 * a `radio` in a `radiogroup`); otherwise a static star row (`role="img"`) that honestly renders a
 * **fractional** fill for averages (a 4.5 renders as a half-filled fifth star, never rounded) via a
 * clip-path overlay — logical, so the filled portion grows from the reading-start side under both `fa`
 * (RTL) and `en` (LTR). Colors resolve from the dedicated `--bal-rating`/`--bal-rating-empty` tokens
 * (retiring the muddy `--bal-warning`/near-invisible `--bal-divider` pairing). Built on the registered
 * `star` `AppIcon` (no MUI `Rating` dependency, so the control is fully deterministic to test).
 * @component RatingInput
 */
const RatingInput: FunctionComponent<RatingInputProps> = ({
  value,
  onChange,
  readOnly = false,
  max = DEFAULT_MAX,
  size = DEFAULT_SIZE,
  ariaLabel,
}) => {
  const locale = useLocale();
  const dir = locale === 'fa' ? 'rtl' : 'ltr';
  const interactive = !readOnly && Boolean(onChange);
  const stars = Array.from({ length: max }, (_, i) => i + 1);

  return (
    <Box
      role={interactive ? 'radiogroup' : 'img'}
      aria-label={ariaLabel}
      data-rating={value}
      data-readonly={readOnly ? 'true' : undefined}
      sx={{ display: 'inline-flex', alignItems: 'center', gap: 0.25 }}
    >
      {stars.map((n) => {
        if (interactive) {
          const filled = n <= value;
          const color = filled ? 'var(--bal-rating)' : 'var(--bal-rating-empty)';
          return (
            <IconButton
              key={n}
              role="radio"
              aria-checked={filled}
              aria-label={String(n)}
              data-star={n}
              size="small"
              onClick={() => onChange?.(n)}
              sx={{ p: 0.25 }}
            >
              <AppIcon icon="star" size={size} color={color} />
            </IconButton>
          );
        }

        // Read-only: fractional fill via a clipped full-star overlay on top of the empty star.
        const fraction = Math.max(0, Math.min(1, value - (n - 1)));
        const fillPercent = fraction * 100;
        const clipPath =
          fraction >= 1 || fraction <= 0
            ? undefined
            : dir === 'rtl'
              ? `inset(0 0 0 ${100 - fillPercent}%)`
              : `inset(0 ${100 - fillPercent}% 0 0)`;

        return (
          <Box key={n} data-star-fraction={fraction} sx={{ position: 'relative', width: size, height: size, lineHeight: 0 }}>
            <AppIcon icon="star" size={size} color="var(--bal-rating-empty)" />
            {fraction > 0 ? (
              <Box sx={{ position: 'absolute', inset: 0, overflow: 'hidden', clipPath }}>
                <AppIcon icon="star" size={size} color="var(--bal-rating)" />
              </Box>
            ) : null}
          </Box>
        );
      })}
    </Box>
  );
};

export default RatingInput;
