import { memo, type PointerEvent } from 'react'
import type { Plant } from '@/lib/plants'
import { computeDerivedCount, type EditorPlanting } from '@/lib/plantings'
import { SELECT_COLOR } from './shared'

// Semantic-zoom thresholds in px/cm (DESIGN § Editor / rendering), tuned by feel:
//   < FAR      — flat color patch, no text ("what's planted where" at a glance)
//   FAR..NEAR  — colored circle + plant emoji
//   ≥ NEAR     — circle + emoji + plant name + count
export const SEMANTIC_FAR = 0.75
export const SEMANTIC_NEAR = 3

const DEFAULT_COLOR = '#6aa84f'

/**
 * One plop, rendered in its parent object's local frame (the caller wraps it in
 * the object's translate+rotate group, so the plop tracks the bed). A circle in
 * the plant's color; emoji and name/count fade in with zoom. The count is
 * computed live from the current radius so it updates while resizing. memo'd so a
 * pan/zoom that only changes the world transform doesn't re-render every plop.
 */
export const PlopMarker = memo(function PlopMarker({
  plop,
  plant,
  scale,
  selected,
  onSelect,
}: {
  plop: EditorPlanting
  plant?: Plant
  scale: number
  selected: boolean
  onSelect: (id: number) => void
}) {
  const color = plant?.color ?? DEFAULT_COLOR
  const r = Math.max(0, plop.radiusCm)
  const showIcon = scale >= SEMANTIC_FAR && !!plant?.icon
  const showText = scale >= SEMANTIC_NEAR && !!plant
  const count = plop.count ?? (plant ? computeDerivedCount(plop.radiusCm, plant.spacingCm) : plop.derivedCount)
  // Keep the tap target at least ~44px across even when the plop draws tiny at
  // low zoom (fill=transparent still receives pointer events, unlike fill=none).
  const hitR = Math.max(r, 22 / scale)

  function down(e: PointerEvent) {
    e.stopPropagation()
    onSelect(plop.id)
  }

  return (
    <g transform={`translate(${plop.xCm} ${plop.yCm})`} onPointerDown={down} style={{ cursor: 'pointer' }}>
      <circle cx={0} cy={0} r={hitR} fill="transparent" />
      <circle
        cx={0}
        cy={0}
        r={r}
        fill={color}
        fillOpacity={0.82}
        stroke={selected ? SELECT_COLOR : '#00000033'}
        strokeWidth={selected ? 2.5 : 1}
        vectorEffect="non-scaling-stroke"
      />
      {showIcon && (
        <text
          x={0}
          y={0}
          fontSize={r * 1.2}
          textAnchor="middle"
          dominantBaseline="central"
          style={{ pointerEvents: 'none', userSelect: 'none' }}
        >
          {plant!.icon}
        </text>
      )}
      {showText && (
        <text
          x={0}
          y={r + r * 0.3}
          fontSize={Math.max(r * 0.5, 6)}
          textAnchor="middle"
          dominantBaseline="hanging"
          fill="#1f2937"
          stroke="#ffffff"
          strokeWidth={0.5}
          paintOrder="stroke"
          style={{ pointerEvents: 'none', userSelect: 'none' }}
        >
          {plant!.name} · {count}
        </text>
      )}
    </g>
  )
})
