import { useEffect, useRef, useState } from 'react'
import { Tooltip } from './Tooltip'
import {
  STEP_COLOR_PRESETS,
  stepColorLabel,
  type StepColorPreset,
} from '../utils/stepColors'
import styles from './StepColorPicker.module.css'

interface StepColorPickerProps {
  value: StepColorPreset
  onChange: (color: StepColorPreset) => void
  disabled?: boolean
  ariaLabel?: string
}

export function StepColorPicker({
  value,
  onChange,
  disabled = false,
  ariaLabel = 'Pick step color',
}: StepColorPickerProps) {
  const [open, setOpen] = useState(false)
  const rootRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    if (!open) return

    function handlePointerDown(event: MouseEvent) {
      if (!rootRef.current?.contains(event.target as Node)) {
        setOpen(false)
      }
    }

    function handleKeyDown(event: KeyboardEvent) {
      if (event.key === 'Escape') setOpen(false)
    }

    document.addEventListener('mousedown', handlePointerDown)
    document.addEventListener('keydown', handleKeyDown)
    return () => {
      document.removeEventListener('mousedown', handlePointerDown)
      document.removeEventListener('keydown', handleKeyDown)
    }
  }, [open])

  function selectColor(color: StepColorPreset) {
    onChange(color)
    setOpen(false)
  }

  return (
    <div className={styles.root} ref={rootRef}>
      <Tooltip label="Pick step color">
        <button
          type="button"
          className={styles.trigger}
          style={{ backgroundColor: value }}
          onClick={() => !disabled && setOpen((current) => !current)}
          disabled={disabled}
          aria-label={ariaLabel}
          aria-haspopup="listbox"
          aria-expanded={open}
        />
      </Tooltip>

      {open && (
        <div className={styles.panel} role="listbox" aria-label="Step colors">
          <div className={styles.grid}>
            {STEP_COLOR_PRESETS.map((color) => {
              const selected = color === value
              return (
                <button
                  key={color}
                  type="button"
                  role="option"
                  aria-selected={selected}
                  aria-label={stepColorLabel(color)}
                  className={`${styles.swatch} ${selected ? styles.swatchSelected : ''}`}
                  style={{ backgroundColor: color }}
                  onClick={() => selectColor(color)}
                />
              )
            })}
          </div>
        </div>
      )}
    </div>
  )
}
