import React, { useCallback, useEffect, useRef, useState } from 'react';
import { Box } from '@/ui/Box';
import { Group } from '@/ui/Group';
import { Stack } from '@/ui/Stack';
import { Text } from '@/ui/Text';
import { Surface } from '@/ui/Surface';
 
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 (
      <Stack gap={1.5}>
        <Group justify="between" gap={3}>
          <Text as="label" size="xs" weight="medium" variant="low">{label}</Text>
          <Box display="flex" alignItems="center" gap={2} flex={1} maxWidth="200px">
            <Box
              as="div"
              ref={sliderRef}
              style={{ 
                position: 'relative',
                flex: 1,
                height: '1.5rem',
                cursor: disabled ? 'not-allowed' : 'pointer', 
                touchAction: 'none',
                opacity: disabled ? 0.5 : 1
              }}
              onPointerDown={handlePointerDown}
              onPointerMove={handlePointerMove}
              onPointerUp={handlePointerUp}
            >
              {/* Track background */}
              <Box position="absolute" top="50%" left={0} right={0} height="0.375rem" rounded="full" bg="var(--ui-color-border-muted)" style={{ transform: 'translateY(-50%)' }} />
              {/* Track fill */}
              <Box
                position="absolute"
                top="50%"
                left={0}
                height="0.375rem"
                rounded="full"
                bg="var(--ui-color-intent-primary)"
                style={{ width: `${rangePercent}%`, transform: 'translateY(-50%)', transition: 'width 75ms' }}
              />
              {/* Thumb */}
              <Box
                position="absolute"
                top="50%"
                width="1rem"
                height="1rem"
                rounded="full"
                bg="white"
                border="2px solid var(--ui-color-intent-primary)"
                shadow="md"
                style={{ 
                  left: `${rangePercent}%`, 
                  transform: `translate(-50%, -50%) ${isDragging ? 'scale(1.25)' : ''}`,
                  transition: 'transform 75ms, left 75ms',
                  boxShadow: isDragging ? '0 0 12px rgba(25, 140, 255, 0.5)' : undefined
                }}
              />
            </Box>
            <Box flexShrink={0}>
              <Group gap={1}>
                <Text size="sm" weight="semibold" variant="high" textAlign="right" width="2rem">{clampedValue}</Text>
                <Text size="xs" variant="low" style={{ fontSize: '10px' }}>{unitLabel}</Text>
              </Group>
            </Box>
          </Box>
        </Group>
        {error && <Text size="xs" variant="critical" style={{ fontSize: '10px' }}>{error}</Text>}
      </Stack>
    );
  }
 
  return (
    <Stack gap={3}>
      <Group justify="between" align="baseline" gap={2}>
        <Text as="label" size="sm" weight="medium" variant="med">{label}</Text>
        <Text size="xs" variant="low" style={{ fontSize: '10px' }}>{effectiveRangeHint}</Text>
      </Group>
 
      {showLargeValue && (
        <Group align="baseline" gap={1}>
          <Text size="3xl" weight="bold" variant="high" font="mono">{clampedValue}</Text>
          <Text size="sm" variant="low">{unitLabel}</Text>
        </Group>
      )}
 
      {/* Custom slider */}
      <Box
        as="div"
        ref={sliderRef}
        style={{ 
          position: 'relative',
          height: '2rem',
          cursor: disabled ? 'not-allowed' : 'pointer', 
          touchAction: 'none', 
          userSelect: 'none',
          opacity: disabled ? 0.5 : 1
        }}
        onPointerDown={handlePointerDown}
        onPointerMove={handlePointerMove}
        onPointerUp={handlePointerUp}
      >
        {/* Track background */}
        <Box position="absolute" top="50%" left={0} right={0} height="0.5rem" rounded="full" bg="var(--ui-color-border-muted)" style={{ transform: 'translateY(-50%)', opacity: 0.8 }} />
        
        {/* Track fill with gradient */}
        <Box
          position="absolute"
          top="50%"
          left={0}
          height="0.5rem"
          rounded="full"
          style={{ 
            width: `${rangePercent}%`, 
            transform: 'translateY(-50%)', 
            transition: 'width 75ms',
            background: 'linear-gradient(to right, var(--ui-color-intent-primary), #00f2ff)'
          }}
        />
 
        {/* Tick marks */}
        <Box position="absolute" top="50%" left={0} right={0} display="flex" justifyContent="between" paddingX={1} style={{ transform: 'translateY(-50%)' }}>
          {[0, 25, 50, 75, 100].map((tick) => (
            <Box
              key={tick}
              width="0.125rem"
              height="0.25rem"
              rounded="full"
              bg={rangePercent >= tick ? 'rgba(255, 255, 255, 0.4)' : 'var(--ui-color-border-muted)'}
              style={{ transition: 'background-color 75ms' }}
            />
          ))}
        </Box>
 
        {/* Thumb */}
        <Box
          position="absolute"
          top="50%"
          width="1.25rem"
          height="1.25rem"
          rounded="full"
          bg="white"
          border="2px solid var(--ui-color-intent-primary)"
          shadow="lg"
          style={{ 
            left: `${rangePercent}%`, 
            transform: `translate(-50%, -50%) ${isDragging ? 'scale(1.25)' : ''}`,
            transition: 'transform 75ms, left 75ms',
            boxShadow: isDragging ? '0 0 16px rgba(25, 140, 255, 0.6)' : '0 2px 8px rgba(0,0,0,0.3)'
          }}
        />
      </Box>
 
      {/* Value input and quick presets */}
      <Group justify="between" align="center" gap={3}>
        <Group gap={2}>
          <Box
            as="input"
            ref={inputRef}
            type="number"
            min={min}
            max={max}
            step={step}
            value={clampedValue}
            onChange={handleInputChange}
            onBlur={handleInputBlur}
            disabled={disabled}
            style={{
              width: '4rem',
              padding: '0.375rem 0.5rem',
              fontSize: '0.875rem',
              fontWeight: 500,
              textAlign: 'center',
              borderRadius: 'var(--ui-radius-lg)',
              backgroundColor: 'var(--ui-color-bg-surface-muted)',
              border: `1px solid ${error ? 'var(--ui-color-intent-critical)' : 'var(--ui-color-border-default)'}`,
              color: 'white',
              outline: 'none',
              opacity: disabled ? 0.5 : 1,
              cursor: disabled ? 'not-allowed' : 'text'
            }}
          />
          <Text size="xs" variant="low">{unitLabel}</Text>
        </Group>
 
        {quickPresets.length > 0 && (
          <Group gap={1}>
            {quickPresets.slice(0, 3).map((preset) => (
              <Box
                as="button"
                key={preset}
                type="button"
                onClick={() => {
                  setLocalValue(preset);
                  onChange(preset);
                }}
                disabled={disabled}
                style={{
                  padding: '0.25rem 0.5rem',
                  fontSize: '10px',
                  borderRadius: 'var(--ui-radius-sm)',
                  backgroundColor: 'rgba(255, 255, 255, 0.05)',
                  color: 'var(--ui-color-text-low)',
                  border: 'none',
                  cursor: disabled ? 'not-allowed' : 'pointer',
                  transition: 'all 150ms'
                }}
              >
                {preset}
              </Box>
            ))}
          </Group>
        )}
      </Group>
 
      {helperText && <Text size="xs" variant="low">{helperText}</Text>}
      {error && <Text size="xs" variant="critical">{error}</Text>}
    </Stack>
  );
}