import { useRef, useState } from 'react'
import { useDraggable } from '@dnd-kit/core'
import { useSortable } from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities'
import { VARIABLES } from '../engine/variables.js'
import { getUnitsForFamily } from '../engine/units.js'
import { formatValue } from '../engine/format.js'

// Card shown in the left palette — draggable
export function PaletteCard({ varId, isInWorkspace }) {
  const { attributes, listeners, setNodeRef, isDragging } = useDraggable({
    id: `palette-${varId}`,
    data: { varId, source: 'palette' },
  })

  const v = VARIABLES[varId]
  if (!v) return null

  return (
    <div
      ref={setNodeRef}
      {...listeners}
      {...attributes}
      className={`
        flex items-center gap-2 px-3 py-2 rounded-lg border text-sm cursor-grab select-none transition-all
        ${isDragging ? 'opacity-40' : ''}
        ${isInWorkspace
          ? 'border-slate-600 bg-slate-800 text-slate-500'
          : 'border-slate-600 bg-slate-700 text-slate-200 hover:border-blue-400 hover:bg-slate-600 active:cursor-grabbing'}
      `}
    >
      <span className="font-mono font-bold text-blue-300 w-10 shrink-0 text-center">{v.symbol}</span>
      <div className="min-w-0">
        <div className="truncate">{v.name}</div>
        <div className="text-xs text-slate-400">{v.units}</div>
      </div>
      {isInWorkspace && (
        <span className="ml-auto text-green-500 text-xs shrink-0">✓</span>
      )}
    </div>
  )
}

// Card shown in the workspace
export function WorkspaceCard({
  varId,
  userValue,
  solvedInfo,
  onRemove,
  onValueChange,
  getUnit,
  onUnitChange,
  sciNotation,
  areaRatioBranch,
  onToggleBranch,
}) {
  const inputRef = useRef(null)
  const [inputError, setInputError] = useState(false)
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging,
  } = useSortable({ id: varId })

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
    opacity: isDragging ? 0.5 : 1,
  }

  const v = VARIABLES[varId]
  if (!v) return null

  const unit = getUnit(varId)
  const availableUnits = getUnitsForFamily(v.unitFamily)

  const isUserSet = userValue !== undefined && userValue !== ''
  const isSolved = !!solvedInfo

  const handleInputChange = (rawDisplayValue) => {
    if (rawDisplayValue === '') {
      setInputError(false)
      onValueChange(rawDisplayValue)
      return
    }
    const parsed = parseFloat(rawDisplayValue)
    if (isNaN(parsed)) return

    // Validate positive constraint
    if (v.positive && parsed < 0) {
      setInputError(true)
      return
    }
    setInputError(false)
    onValueChange(rawDisplayValue)
  }

  // State: user-entered (blue), solved (green), unknown (grey), error (red)
  const borderColor = inputError ? 'border-red-500' : isUserSet ? 'border-blue-500' : isSolved ? 'border-green-500' : 'border-slate-600'
  const symbolColor = inputError ? 'text-red-300' : isUserSet ? 'text-blue-300' : isSolved ? 'text-green-300' : 'text-slate-400'
  const valueBg = inputError ? 'bg-red-950' : isUserSet ? 'bg-blue-950' : isSolved ? 'bg-green-950' : 'bg-slate-800'

  // Display value converted from stored SI to current display unit
  const inputDisplayValue = isUserSet
    ? parseFloat(unit.fromSI(userValue).toPrecision(10))
    : ''

  const siUnit = availableUnits[0]
  const isNonSI = unit.id !== siUnit.id

  return (
    <div
      ref={setNodeRef}
      style={style}
      className={`rounded-xl border-2 ${borderColor} bg-slate-800 p-3 flex flex-col gap-1 relative group ${isDragging ? 'opacity-50' : ''}`}
      {...attributes}
      {...listeners}
    >
      <button
        onClick={onRemove}
        className="absolute top-1.5 right-1.5 w-5 h-5 rounded-full bg-slate-700 text-slate-400 hover:bg-red-700 hover:text-white opacity-0 group-hover:opacity-100 transition-all text-xs flex items-center justify-center leading-none"
        title="Remove from workspace"
      >
        ×
      </button>
      <div className="flex items-baseline gap-2">
        <span className={`font-mono font-bold text-lg ${symbolColor}`}>{v.symbol}</span>
        {availableUnits.length > 1 ? (
          <select
            value={unit.id}
            onChange={e => onUnitChange(e.target.value)}
            className={`text-xs rounded px-1.5 py-0.5 border outline-none cursor-pointer transition-colors ${
              isNonSI
                ? 'bg-violet-900/40 text-violet-200 border-violet-600 hover:border-violet-400'
                : 'bg-transparent text-slate-400 border-transparent hover:border-slate-500 hover:text-slate-300'
            }`}
          >
            {availableUnits.map(u => (
              <option key={u.id} value={u.id} className="bg-slate-800 text-slate-200">{u.label}</option>
            ))}
          </select>
        ) : (
          <span className="text-slate-400 text-xs">{unit.label}</span>
        )}
        {isSolved && varId === 'Me' && solvedInfo?.equationName === 'Isentropic Area Ratio' && onToggleBranch && (
          <button
            onClick={onToggleBranch}
            title={`Switch to ${areaRatioBranch === 'supersonic' ? 'subsonic' : 'supersonic'}`}
            className="ml-auto text-xs px-1.5 py-0.5 rounded border transition-colors bg-amber-900/40 text-amber-300 border-amber-600 hover:border-amber-400 hover:bg-amber-900/60"
          >
            {areaRatioBranch === 'supersonic' ? 'SS' : 'Sub'}
          </button>
        )}
      </div>
      <div className="text-slate-300 text-xs truncate">{v.name}</div>
      <div className={`mt-1 rounded-md ${valueBg} px-2 py-1`}>
        {isSolved && !isUserSet ? (
          <div>
            <div className="font-mono text-green-300 text-sm font-semibold">
              {formatValue(unit.fromSI(solvedInfo.value), sciNotation)}
            </div>
            {isNonSI && (
              <div className="text-green-700 text-[10px] mt-0.5 font-mono">
                = {formatValue(solvedInfo.value, sciNotation)} {siUnit.label}
              </div>
            )}
            <div className="text-green-600 text-xs mt-0.5">via {solvedInfo.equationName}</div>
          </div>
        ) : (
          <div>
            <input
              ref={inputRef}
              type="number"
              value={inputDisplayValue}
              onChange={e => handleInputChange(e.target.value)}
              placeholder="Enter value…"
              className={`w-full bg-transparent font-mono text-sm ${inputError ? 'text-red-200' : 'text-blue-200'} placeholder-slate-600 outline-none`}
            />
            {inputError && (
              <p className="text-xs text-red-400 mt-0.5">Must be positive</p>
            )}
            {isUserSet && isNonSI && !inputError && (
              <div className="text-blue-800 text-[10px] mt-0.5 font-mono">
                = {formatValue(userValue, sciNotation)} {siUnit.label}
              </div>
            )}
          </div>
        )}
      </div>
    </div>
  )
}
