"use client";

import React, { useState, useCallback } from 'react';

export interface RatingProps {
  /** Current value (controlled) */
  value?: number;
  /** Default value */
  defaultValue?: number;
  /** Maximum rating value */
  max?: number;
  /** Callback when value changes */
  onChange?: (value: number) => void;
  /** Allow half values */
  allowHalf?: boolean;
  /** Allow clearing (clicking same value) */
  allowClear?: boolean;
  /** Disabled state */
  disabled?: boolean;
  /** Read-only state */
  readOnly?: boolean;
  /** Size variant */
  size?: 'sm' | 'md' | 'lg';
  /** Color */
  color?: string;
  /** Empty color */
  emptyColor?: string;
  /** Custom icon */
  icon?: React.ReactNode;
  /** Custom empty icon */
  emptyIcon?: React.ReactNode;
  /** Custom half icon */
  halfIcon?: React.ReactNode;
  /** Character to display (alternative to icon) */
  character?: React.ReactNode;
  /** Show value text */
  showValue?: boolean;
  /** Custom value formatter */
  formatValue?: (value: number) => string;
  /** Tooltips for each value */
  tooltips?: string[];
  /** Additional CSS classes */
  className?: string;
}

const StarIcon: React.FC<{ filled?: boolean; half?: boolean }> = ({ filled, half }) => (
  <svg viewBox="0 0 24 24" width="1em" height="1em" fill={filled || half ? 'currentColor' : 'none'} stroke="currentColor" strokeWidth="2">
    {half ? (
      <>
        <defs>
          <linearGradient id="half-star">
            <stop offset="50%" stopColor="currentColor" />
            <stop offset="50%" stopColor="transparent" />
          </linearGradient>
        </defs>
        <path fill="url(#half-star)" d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" />
      </>
    ) : (
      <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" />
    )}
  </svg>
);

export const Rating: React.FC<RatingProps> = ({
  value: controlledValue,
  defaultValue = 0,
  max = 5,
  onChange,
  allowHalf = false,
  allowClear = true,
  disabled = false,
  readOnly = false,
  size = 'md',
  color = '#ffc107',
  emptyColor = '#e0e0e0',
  icon,
  emptyIcon,
  halfIcon,
  character,
  showValue = false,
  formatValue = (v) => v.toFixed(allowHalf ? 1 : 0),
  tooltips,
  className = '',
}) => {
  const [internalValue, setInternalValue] = useState(defaultValue);
  const [hoverValue, setHoverValue] = useState<number | null>(null);

  const value = controlledValue ?? internalValue;
  const displayValue = hoverValue ?? value;

  const handleClick = useCallback((newValue: number) => {
    if (disabled || readOnly) return;

    // Allow clear if clicking same value
    const finalValue = allowClear && newValue === value ? 0 : newValue;

    if (controlledValue === undefined) {
      setInternalValue(finalValue);
    }
    onChange?.(finalValue);
  }, [disabled, readOnly, allowClear, value, controlledValue, onChange]);

  const handleMouseMove = useCallback((e: React.MouseEvent, index: number) => {
    if (disabled || readOnly) return;

    const rect = e.currentTarget.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const isHalf = allowHalf && x < rect.width / 2;

    setHoverValue(isHalf ? index + 0.5 : index + 1);
  }, [disabled, readOnly, allowHalf]);

  const handleMouseLeave = () => {
    setHoverValue(null);
  };

  const renderStar = (index: number) => {
    const starValue = index + 1;
    const isFilled = displayValue >= starValue;
    const isHalf = allowHalf && displayValue >= index + 0.5 && displayValue < starValue;
    const isActive = !disabled && !readOnly;

    let starIcon: React.ReactNode;

    if (character) {
      starIcon = character;
    } else if (isHalf && halfIcon) {
      starIcon = halfIcon;
    } else if (isFilled && icon) {
      starIcon = icon;
    } else if (!isFilled && emptyIcon) {
      starIcon = emptyIcon;
    } else {
      starIcon = <StarIcon filled={isFilled} half={isHalf} />;
    }

    const tooltip = tooltips?.[index];

    return (
      <span
        key={index}
        className={`ll-rating-star ${isFilled || isHalf ? 'll-rating-star-filled' : 'll-rating-star-empty'}`}
        style={{
          color: isFilled || isHalf ? color : emptyColor,
          cursor: isActive ? 'pointer' : 'default',
        }}
        onClick={() => handleClick(allowHalf && isHalf ? index + 0.5 : starValue)}
        onMouseMove={(e) => handleMouseMove(e, index)}
        title={tooltip}
        role="radio"
        aria-checked={value === starValue}
      >
        {starIcon}
      </span>
    );
  };

  const classes = [
    'll-rating',
    `ll-rating-${size}`,
    disabled && 'll-rating-disabled',
    readOnly && 'll-rating-readonly',
    className,
  ].filter(Boolean).join(' ');

  return (
    <div
      className={classes}
      onMouseLeave={handleMouseLeave}
      role="radiogroup"
      aria-label="Rating"
    >
      <div className="ll-rating-stars">
        {Array.from({ length: max }, (_, i) => renderStar(i))}
      </div>
      {showValue && (
        <span className="ll-rating-value">{formatValue(displayValue)}</span>
      )}
    </div>
  );
};

// Heart Rating variant
export const HeartRating: React.FC<Omit<RatingProps, 'icon' | 'emptyIcon'>> = (props) => {
  const HeartIcon = ({ filled }: { filled: boolean }) => (
    <svg viewBox="0 0 24 24" width="1em" height="1em" fill={filled ? 'currentColor' : 'none'} stroke="currentColor" strokeWidth="2">
      <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" />
    </svg>
  );

  return (
    <Rating
      {...props}
      color={props.color || '#e91e63'}
      icon={<HeartIcon filled />}
      emptyIcon={<HeartIcon filled={false} />}
    />
  );
};

// Emoji Rating variant
export interface EmojiRatingProps extends Omit<RatingProps, 'icon' | 'emptyIcon' | 'character' | 'max'> {
  emojis?: string[];
}

export const EmojiRating: React.FC<EmojiRatingProps> = ({
  emojis = ['😞', '😕', '😐', '🙂', '😄'],
  ...props
}) => {
  const max = emojis.length;

  return (
    <div className="ll-emoji-rating">
      <Rating
        {...props}
        max={max}
        allowHalf={false}
        icon={null}
        emptyIcon={null}
      />
      <div className="ll-emoji-rating-faces">
        {emojis.map((emoji, index) => (
          <span
            key={index}
            className={`ll-emoji-rating-face ${(props.value ?? props.defaultValue ?? 0) >= index + 1 ? 'active' : ''}`}
          >
            {emoji}
          </span>
        ))}
      </div>
    </div>
  );
};
