'use client'

import { useEffect, useRef, useState } from 'react'

interface CompassSelectorProps {
  value: number // 0-360 degrees
  onChange: (value: number) => void
  range?: number // Optional range to display as arc (±degrees)
  size?: number
  className?: string
}

export function CompassSelector({ value, onChange, range, size = 200, className = '' }: CompassSelectorProps) {
  const [isDragging, setIsDragging] = useState(false)
  const compassRef = useRef<SVGSVGElement>(null)

  const handlePointerMove = (e: PointerEvent) => {
    if (!isDragging || !compassRef.current) return

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

    const dx = e.clientX - centerX
    const dy = e.clientY - centerY

    // Calculate angle in degrees (0° = North/top)
    let angle = Math.atan2(dx, -dy) * (180 / Math.PI)
    if (angle < 0) angle += 360

    // Round to nearest 5 degrees for easier selection
    angle = Math.round(angle / 5) * 5

    onChange(angle % 360)
  }

  const handlePointerDown = (e: React.PointerEvent) => {
    setIsDragging(true)
    // Trigger initial update
    const rect = compassRef.current!.getBoundingClientRect()
    const centerX = rect.left + rect.width / 2
    const centerY = rect.top + rect.height / 2

    const dx = e.clientX - centerX
    const dy = e.clientY - centerY

    let angle = Math.atan2(dx, -dy) * (180 / Math.PI)
    if (angle < 0) angle += 360
    angle = Math.round(angle / 5) * 5

    onChange(angle % 360)
  }

  const handlePointerUp = () => {
    setIsDragging(false)
  }

  useEffect(() => {
    if (isDragging) {
      window.addEventListener('pointermove', handlePointerMove)
      window.addEventListener('pointerup', handlePointerUp)

      return () => {
        window.removeEventListener('pointermove', handlePointerMove)
        window.removeEventListener('pointerup', handlePointerUp)
      }
    }
  }, [isDragging])

  // Convert degrees to radians for calculations
  const angleRad = (value - 90) * (Math.PI / 180)
  const radius = size / 2 - 10
  const needleLength = radius * 0.7

  // Calculate needle endpoint
  const needleX = size / 2 + Math.cos(angleRad) * needleLength
  const needleY = size / 2 + Math.sin(angleRad) * needleLength

  // Helper to convert degrees to compass direction
  const getCompassDirection = (degrees: number): string => {
    const directions = ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW']
    const index = Math.round(degrees / 22.5) % 16
    return directions[index]
  }

  return (
    <div className={`flex flex-col items-center ${className}`}>
      <svg
        ref={compassRef}
        width={size}
        height={size}
        className="cursor-pointer select-none"
        onPointerDown={handlePointerDown}
        style={{ touchAction: 'none' }}
      >
        {/* Outer circle */}
        <circle
          cx={size / 2}
          cy={size / 2}
          r={radius}
          fill="hsl(var(--secondary))"
          stroke="hsl(var(--border))"
          strokeWidth="2"
        />

        {/* Acceptable range arc (green) */}
        {range !== undefined && (() => {
          const startAngle = value - range
          const endAngle = value + range

          // Convert to radians for calculation (adjusting for SVG coordinate system)
          const startRad = (startAngle - 90) * (Math.PI / 180)
          const endRad = (endAngle - 90) * (Math.PI / 180)

          // Calculate start and end points on the circle
          const x1 = size / 2 + Math.cos(startRad) * radius
          const y1 = size / 2 + Math.sin(startRad) * radius
          const x2 = size / 2 + Math.cos(endRad) * radius
          const y2 = size / 2 + Math.sin(endRad) * radius

          // Determine if the arc should be large (>180°) or small
          const largeArcFlag = range * 2 > 180 ? 1 : 0

          // Create SVG arc path
          const arcPath = `M ${x1} ${y1} A ${radius} ${radius} 0 ${largeArcFlag} 1 ${x2} ${y2}`

          return (
            <path
              d={arcPath}
              fill="none"
              stroke="#22c55e"
              strokeWidth="6"
              strokeLinecap="round"
            />
          )
        })()}

        {/* Cardinal direction markers */}
        {[
          { angle: 0, label: 'N' },
          { angle: 90, label: 'E' },
          { angle: 180, label: 'S' },
          { angle: 270, label: 'W' },
        ].map(({ angle, label }) => {
          const rad = (angle - 90) * (Math.PI / 180)
          const x = size / 2 + Math.cos(rad) * (radius - 20)
          const y = size / 2 + Math.sin(rad) * (radius - 20)

          return (
            <text
              key={angle}
              x={x}
              y={y}
              textAnchor="middle"
              dominantBaseline="middle"
              className="text-sm font-bold fill-foreground"
            >
              {label}
            </text>
          )
        })}

        {/* Degree tick marks every 30° */}
        {Array.from({ length: 12 }, (_, i) => {
          const angle = i * 30
          const rad = (angle - 90) * (Math.PI / 180)
          const x1 = size / 2 + Math.cos(rad) * (radius - 5)
          const y1 = size / 2 + Math.sin(rad) * (radius - 5)
          const x2 = size / 2 + Math.cos(rad) * radius
          const y2 = size / 2 + Math.sin(rad) * radius

          return (
            <line
              key={angle}
              x1={x1}
              y1={y1}
              x2={x2}
              y2={y2}
              stroke="hsl(var(--border))"
              strokeWidth="2"
            />
          )
        })}

        {/* Center dot */}
        <circle
          cx={size / 2}
          cy={size / 2}
          r="4"
          fill="hsl(var(--primary))"
        />

        {/* Direction needle */}
        <line
          x1={size / 2}
          y1={size / 2}
          x2={needleX}
          y2={needleY}
          stroke="hsl(var(--primary))"
          strokeWidth="3"
          strokeLinecap="round"
        />

        {/* Needle tip */}
        <circle
          cx={needleX}
          cy={needleY}
          r="6"
          fill="hsl(var(--primary))"
          stroke="hsl(var(--background))"
          strokeWidth="2"
        />
      </svg>

      {/* Value display */}
      <div className="mt-2 text-center">
        <div className="text-lg font-bold">{value}° ({getCompassDirection(value)})</div>
      </div>
    </div>
  )
}
