'use client';

import * as React from 'react';
import { cn } from '@/lib/utils/cn';

export interface CircularKnobProps {
  value: number; // -1.0 to 1.0 for pan
  onChange: (value: number) => void;
  min?: number;
  max?: number;
  step?: number;
  size?: number;
  className?: string;
  label?: string;
  formatValue?: (value: number) => string;
}

export function CircularKnob({
  value,
  onChange,
  min = -1,
  max = 1,
  step = 0.01,
  size = 48,
  className,
  label,
  formatValue,
}: CircularKnobProps) {
  const knobRef = React.useRef<HTMLDivElement>(null);
  const [isDragging, setIsDragging] = React.useState(false);
  const dragStartRef = React.useRef({ x: 0, y: 0, value: 0 });

  const updateValue = React.useCallback(
    (clientX: number, clientY: number) => {
      if (!knobRef.current) return;

      const rect = knobRef.current.getBoundingClientRect();
      const centerX = rect.left + rect.width / 2;
      const centerY = rect.top + rect.height / 2;

      // Calculate vertical drag distance from start
      const deltaY = dragStartRef.current.y - clientY;
      const sensitivity = 200; // pixels for full range
      const range = max - min;
      const delta = (deltaY / sensitivity) * range;

      let newValue = dragStartRef.current.value + delta;

      // Snap to step
      if (step) {
        newValue = Math.round(newValue / step) * step;
      }

      // Clamp to range
      newValue = Math.max(min, Math.min(max, newValue));

      onChange(newValue);
    },
    [min, max, step, onChange]
  );

  const handleMouseDown = React.useCallback(
    (e: React.MouseEvent) => {
      e.preventDefault();
      setIsDragging(true);
      dragStartRef.current = {
        x: e.clientX,
        y: e.clientY,
        value,
      };
    },
    [value]
  );

  const handleMouseMove = React.useCallback(
    (e: MouseEvent) => {
      if (isDragging) {
        updateValue(e.clientX, e.clientY);
      }
    },
    [isDragging, updateValue]
  );

  const handleMouseUp = React.useCallback(() => {
    setIsDragging(false);
  }, []);

  React.useEffect(() => {
    if (isDragging) {
      window.addEventListener('mousemove', handleMouseMove);
      window.addEventListener('mouseup', handleMouseUp);

      return () => {
        window.removeEventListener('mousemove', handleMouseMove);
        window.removeEventListener('mouseup', handleMouseUp);
      };
    }
  }, [isDragging, handleMouseMove, handleMouseUp]);

  // Calculate rotation angle (-135deg to 135deg, 270deg range)
  const percentage = (value - min) / (max - min);
  const angle = -135 + percentage * 270;

  const displayValue = formatValue
    ? formatValue(value)
    : value === 0
    ? 'C'
    : value < 0
    ? `L${Math.abs(Math.round(value * 100))}`
    : `R${Math.round(value * 100)}`;

  return (
    <div className={cn('flex flex-col items-center gap-1', className)}>
      {label && (
        <div className="text-[10px] text-muted-foreground uppercase tracking-wide">
          {label}
        </div>
      )}

      <div
        ref={knobRef}
        onMouseDown={handleMouseDown}
        className="relative cursor-pointer select-none"
        style={{ width: size, height: size }}
      >
        {/* Outer ring */}
        <svg
          width={size}
          height={size}
          viewBox={`0 0 ${size} ${size}`}
          className="absolute inset-0"
        >
          {/* Background arc */}
          <circle
            cx={size / 2}
            cy={size / 2}
            r={size / 2 - 4}
            fill="none"
            stroke="currentColor"
            strokeWidth="2"
            className="text-muted/30"
          />

          {/* Value arc */}
          <circle
            cx={size / 2}
            cy={size / 2}
            r={size / 2 - 4}
            fill="none"
            stroke="currentColor"
            strokeWidth="3"
            strokeLinecap="round"
            className="text-primary"
            strokeDasharray={`${(percentage * 270 * Math.PI * (size / 2 - 4)) / 180} ${(Math.PI * 2 * (size / 2 - 4))}`}
            transform={`rotate(-225 ${size / 2} ${size / 2})`}
          />
        </svg>

        {/* Knob body */}
        <div
          className="absolute inset-0 rounded-full bg-card border-2 border-border shadow-sm flex items-center justify-center transition-transform hover:scale-105 active:scale-95"
          style={{
            transform: `rotate(${angle}deg)`,
            margin: '4px',
          }}
        >
          {/* Indicator line */}
          <div className="absolute top-1 left-1/2 w-0.5 h-2 bg-primary rounded-full -translate-x-1/2" />
        </div>

        {/* Center dot (for zero position) */}
        {value === 0 && (
          <div className="absolute top-1/2 left-1/2 w-1 h-1 bg-primary rounded-full -translate-x-1/2 -translate-y-1/2" />
        )}
      </div>

      {/* Value Display */}
      <div className="text-[10px] font-medium text-foreground min-w-[32px] text-center">
        {displayValue}
      </div>
    </div>
  );
}
