

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

interface RangeFieldProps {
  label: string;
  value: number;
  min: number;
  max: number;
  step?: number;
  onChange: (value: number) => void;
  helperText?: string;
  error?: string | undefined;
  disabled?: boolean;
  unitLabel?: string;
  rangeHint?: string;
  /** Show large value display above slider */
  showLargeValue?: boolean;
  /** Compact mode - single line */
  compact?: boolean;
}

export function RangeField({
  label,
  value,
  min,
  max,
  step = 1,
  onChange,
  helperText,
  error,
  disabled,
  unitLabel = 'min',
  rangeHint,
  showLargeValue = false,
  compact = false,
}: RangeFieldProps) {
  const [localValue, setLocalValue] = useState(value);
  const [isDragging, setIsDragging] = useState(false);
  const sliderRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLInputElement>(null);

  // Sync local value with prop when not dragging
  useEffect(() => {
    if (!isDragging) {
      setLocalValue(value);
    }
  }, [value, isDragging]);

  const clampedValue = Number.isFinite(localValue)
    ? Math.min(Math.max(localValue, min), max)
    : min;

  const rangePercent = ((clampedValue - min) / Math.max(max - min, 1)) * 100;

  const effectiveRangeHint =
    rangeHint ?? (min === 0 ? `Up to ${max} ${unitLabel}` : `${min}–${max} ${unitLabel}`);

  const calculateValueFromPosition = useCallback(
    (clientX: number) => {
      if (!sliderRef.current) return clampedValue;
      const rect = sliderRef.current.getBoundingClientRect();
      const percent = Math.min(Math.max((clientX - rect.left) / rect.width, 0), 1);
      const rawValue = min + percent * (max - min);
      const steppedValue = Math.round(rawValue / step) * step;
      return Math.min(Math.max(steppedValue, min), max);
    },
    [min, max, step, clampedValue]
  );

  const handlePointerDown = useCallback(
    (e: React.PointerEvent) => {
      if (disabled) return;
      e.preventDefault();
      setIsDragging(true);
      const newValue = calculateValueFromPosition(e.clientX);
      setLocalValue(newValue);
      onChange(newValue);
      (e.target as HTMLElement).setPointerCapture(e.pointerId);
    },
    [disabled, calculateValueFromPosition, onChange]
  );

  const handlePointerMove = useCallback(
    (e: React.PointerEvent) => {
      if (!isDragging || disabled) return;
      const newValue = calculateValueFromPosition(e.clientX);
      setLocalValue(newValue);
      onChange(newValue);
    },
    [isDragging, disabled, calculateValueFromPosition, onChange]
  );

  const handlePointerUp = useCallback(() => {
    setIsDragging(false);
  }, []);

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const raw = e.target.value;
    if (raw === '') {
      setLocalValue(min);
      return;
    }
    const parsed = parseInt(raw, 10);
    if (!Number.isNaN(parsed)) {
      const clamped = Math.min(Math.max(parsed, min), max);
      setLocalValue(clamped);
      onChange(clamped);
    }
  };

  const handleInputBlur = () => {
    // Ensure value is synced on blur
    onChange(clampedValue);
  };

  // Quick preset buttons for common values
  const quickPresets = [
    Math.round(min + (max - min) * 0.25),
    Math.round(min + (max - min) * 0.5),
    Math.round(min + (max - min) * 0.75),
  ].filter((v, i, arr) => arr.indexOf(v) === i && v !== clampedValue);

  if (compact) {
    return (
      <div className="space-y-1.5">
        <div className="flex items-center justify-between gap-3">
          <label className="text-xs font-medium text-gray-400 shrink-0">{label}</label>
          <div className="flex items-center gap-2 flex-1 max-w-[200px]">
            <div
              ref={sliderRef}
              className={`relative flex-1 h-6 cursor-pointer touch-none ${disabled ? 'opacity-50 cursor-not-allowed' : ''}`}
              onPointerDown={handlePointerDown}
              onPointerMove={handlePointerMove}
              onPointerUp={handlePointerUp}
            >
              {/* Track background */}
              <div className="absolute top-1/2 -translate-y-1/2 left-0 right-0 h-1.5 rounded-full bg-charcoal-outline" />
              {/* Track fill */}
              <div
                className="absolute top-1/2 -translate-y-1/2 left-0 h-1.5 rounded-full bg-primary-blue transition-all duration-75"
                style={{ width: `${rangePercent}%` }}
              />
              {/* Thumb */}
              <div
                className={`
                  absolute top-1/2 -translate-y-1/2 -translate-x-1/2 w-4 h-4 rounded-full
                  bg-white border-2 border-primary-blue shadow-md
                  transition-transform duration-75
                  ${isDragging ? 'scale-125 shadow-[0_0_12px_rgba(25,140,255,0.5)]' : ''}
                `}
                style={{ left: `${rangePercent}%` }}
              />
            </div>
            <div className="flex items-center gap-1 shrink-0">
              <span className="text-sm font-semibold text-white w-8 text-right">{clampedValue}</span>
              <span className="text-[10px] text-gray-500">{unitLabel}</span>
            </div>
          </div>
        </div>
        {error && <p className="text-[10px] text-warning-amber">{error}</p>}
      </div>
    );
  }

  return (
    <div className="space-y-3">
      <div className="flex items-baseline justify-between gap-2">
        <label className="block text-sm font-medium text-gray-300">{label}</label>
        <span className="text-[10px] text-gray-500">{effectiveRangeHint}</span>
      </div>

      {showLargeValue && (
        <div className="flex items-baseline gap-1">
          <span className="text-3xl font-bold text-white tabular-nums">{clampedValue}</span>
          <span className="text-sm text-gray-400">{unitLabel}</span>
        </div>
      )}

      {/* Custom slider */}
      <div
        ref={sliderRef}
        className={`relative h-8 cursor-pointer touch-none select-none ${disabled ? 'opacity-50 cursor-not-allowed' : ''}`}
        onPointerDown={handlePointerDown}
        onPointerMove={handlePointerMove}
        onPointerUp={handlePointerUp}
      >
        {/* Track background */}
        <div className="absolute top-1/2 -translate-y-1/2 left-0 right-0 h-2 rounded-full bg-charcoal-outline/80" />
        
        {/* Track fill with gradient */}
        <div
          className="absolute top-1/2 -translate-y-1/2 left-0 h-2 rounded-full bg-gradient-to-r from-primary-blue to-neon-aqua transition-all duration-75"
          style={{ width: `${rangePercent}%` }}
        />

        {/* Tick marks */}
        <div className="absolute top-1/2 -translate-y-1/2 left-0 right-0 flex justify-between px-1">
          {[0, 25, 50, 75, 100].map((tick) => (
            <div
              key={tick}
              className={`w-0.5 h-1 rounded-full transition-colors ${
                rangePercent >= tick ? 'bg-white/40' : 'bg-charcoal-outline'
              }`}
            />
          ))}
        </div>

        {/* Thumb */}
        <div
          className={`
            absolute top-1/2 -translate-y-1/2 -translate-x-1/2
            w-5 h-5 rounded-full bg-white border-2 border-primary-blue
            shadow-[0_2px_8px_rgba(0,0,0,0.3)]
            transition-all duration-75
            ${isDragging ? 'scale-125 shadow-[0_0_16px_rgba(25,140,255,0.6)]' : 'hover:scale-110'}
          `}
          style={{ left: `${rangePercent}%` }}
        />
      </div>

      {/* Value input and quick presets */}
      <div className="flex items-center justify-between gap-3">
        <div className="flex items-center gap-2">
          <input
            ref={inputRef}
            type="number"
            min={min}
            max={max}
            step={step}
            value={clampedValue}
            onChange={handleInputChange}
            onBlur={handleInputBlur}
            disabled={disabled}
            className={`
              w-16 px-2 py-1.5 text-sm font-medium text-center rounded-lg
              bg-iron-gray border border-charcoal-outline text-white
              focus:border-primary-blue focus:ring-1 focus:ring-primary-blue focus:outline-none
              transition-colors
              ${error ? 'border-warning-amber' : ''}
              ${disabled ? 'opacity-50 cursor-not-allowed' : ''}
            `}
          />
          <span className="text-xs text-gray-400">{unitLabel}</span>
        </div>

        {quickPresets.length > 0 && (
          <div className="flex gap-1">
            {quickPresets.slice(0, 3).map((preset) => (
              <button
                key={preset}
                type="button"
                onClick={() => {
                  setLocalValue(preset);
                  onChange(preset);
                }}
                disabled={disabled}
                className="px-2 py-1 text-[10px] rounded bg-charcoal-outline/50 text-gray-400 hover:bg-charcoal-outline hover:text-white transition-colors"
              >
                {preset}
              </button>
            ))}
          </div>
        )}
      </div>

      {helperText && <p className="text-xs text-gray-500">{helperText}</p>}
      {error && <p className="text-xs text-warning-amber">{error}</p>}
    </div>
  );
}