/**
 * RangeSlider component for settings UI.
 */

import React, { useRef } from "react";

export type RangeSliderProps = {
  /** Label displayed above the slider */
  label?: string;
  /** Description text below the label */
  description?: string;
  /** Current value */
  value: number;
  /** Minimum value */
  min: number;
  /** Maximum value */
  max: number;
  /** Step increment (default: 1) */
  step?: number;
  /** Unit suffix (e.g., 'px', '%') */
  unit?: string;
  /** Change handler */
  onChange: (value: number) => void;
  /** Additional class names for the container */
  className?: string;
  /** Whether to span full width in grid (col-span-2) */
  fullWidth?: boolean;
};

export function RangeSlider({
  label,
  description,
  value,
  min,
  max,
  step = 1,
  unit = "px",
  onChange,
  className = "",
  fullWidth = false,
}: RangeSliderProps): React.ReactElement {
  const containerClass = `b3-wvs-relative${fullWidth ? " b3-wvs-col-span-2" : ""}${className ? ` ${className}` : ""}`;
  const tooltipRef = useRef<HTMLDivElement>(null);
  const precision = (() => {
    const stepText = String(step);
    const dotIndex = stepText.indexOf(".");
    return dotIndex >= 0 ? stepText.length - dotIndex - 1 : 0;
  })();

  const parseNumeric = (rawValue: string, fallback: number): number => {
    const parsed = Number(rawValue);
    return Number.isFinite(parsed) ? parsed : fallback;
  };

  const formatValue = (rawValue: number): string => {
    if (!Number.isFinite(rawValue)) return String(min);
    if (precision <= 0) return String(Math.round(rawValue));
    return rawValue.toFixed(precision).replace(/\.?0+$/, "");
  };
  const rangePercent = (() => {
    if (max <= min) return 0;
    const pct = ((value - min) / (max - min)) * 100;
    return Math.min(100, Math.max(0, pct));
  })();

  const updateTooltipPosition = (inputEl: HTMLInputElement) => {
    const tooltip = tooltipRef.current;
    if (!tooltip) return;
    const val = parseNumeric(inputEl.value, value);
    const percentage = ((val - min) / (max - min)) * 100;
    tooltip.style.left = `${percentage}%`;
    tooltip.textContent = `${formatValue(val)}${unit}`;
  };

  return (
    <div className={containerClass}>
      {label && (
        <label className="b3-wvs-block b3-wvs-text-sm b3-wvs-font-medium b3-wvs-text-gray-700 b3-wvs-mb-1">
          {label}
        </label>
      )}
      {description && (
        <p className="b3-wvs-text-xs b3-wvs-text-gray-500 b3-wvs-mb-1">
          {description}
        </p>
      )}
      <div className="b3-wvs-range-wrap">
        <input
          type="range"
          min={min}
          max={max}
          step={step}
          value={value}
          onChange={(e) => onChange(parseNumeric(e.target.value, value))}
          onMouseDown={(e) => {
            const tooltip = tooltipRef.current;
            if (tooltip) {
              tooltip.style.opacity = "1";
              updateTooltipPosition(e.currentTarget);
            }
          }}
          onMouseUp={() => {
            const tooltip = tooltipRef.current;
            if (tooltip) tooltip.style.opacity = "0";
          }}
          onMouseLeave={() => {
            const tooltip = tooltipRef.current;
            if (tooltip) tooltip.style.opacity = "0";
          }}
          onInput={(e) =>
            updateTooltipPosition(e.currentTarget as HTMLInputElement)
          }
          className="b3-wvs-range-input"
          style={
            { "--b3-range-pct": `${rangePercent}%` } as React.CSSProperties
          }
        />
        <div
          ref={tooltipRef}
          className="b3-wvs-absolute b3-wvs-top-[-30px] b3-wvs-bg-gray-800 b3-wvs-text-white b3-wvs-px-2 b3-wvs-py-1 b3-wvs-rounded b3-wvs-text-xs b3-wvs-pointer-events-none b3-wvs-transition-opacity b3-wvs-duration-200 b3-wvs-whitespace-nowrap"
          style={{ opacity: 0, transform: "translateX(-50%)" }}
        >
          {formatValue(value)}
          {unit}
        </div>
      </div>
      <div className="b3-wvs-flex b3-wvs-justify-between b3-wvs-text-xs b3-wvs-text-gray-500">
        <span>
          {formatValue(min)}
          {unit}
        </span>
        <span>
          Currently {formatValue(value)}
          {unit}
        </span>
        <span>
          {formatValue(max)}
          {unit}
        </span>
      </div>
    </div>
  );
}

export default RangeSlider;
