import { ENGINE_CONTROLS } from '../config/effects'
import { getComplexityLabel, getBitDepthLabel, getSampleRateLabel } from '../utils/formatters'
import type { EffectValues } from '../types/effects'
import { Knob } from './Knob'

interface EngineControlsProps {
  values: EffectValues
  onChange: (parameterId: string, value: number) => void
  onMapClick?: (paramId: string, lfoIndex: number) => void
  getMappedLFOs?: (paramId: string) => number[]
}

const KNOB_PARAMS = ['masterVolume', 'pitch', 'a', 'b', 'c', 'd']

export function EngineControls({ values, onChange, onMapClick, getMappedLFOs }: EngineControlsProps) {
  const formatValue = (id: string, value: number): string => {
    switch (id) {
      case 'sampleRate':
        return getSampleRateLabel(value)
      case 'complexity':
        return getComplexityLabel(value)
      case 'bitDepth':
        return getBitDepthLabel(value)
      default: {
        const param = ENGINE_CONTROLS[0].parameters.find(p => p.id === id)
        return `${value}${param?.unit || ''}`
      }
    }
  }

  return (
    <div className="flex items-center gap-6">
      {ENGINE_CONTROLS[0].parameters.map(param => {
        const useKnob = KNOB_PARAMS.includes(param.id)

        if (useKnob) {
          return (
            <Knob
              key={param.id}
              label={param.label}
              value={(values[param.id] as number) ?? param.default}
              min={param.min as number}
              max={param.max as number}
              step={param.step as number}
              unit={param.unit}
              onChange={(value) => onChange(param.id, value)}
              formatValue={formatValue}
              valueId={param.id}
              paramId={param.id}
              onMapClick={onMapClick}
              mappedLFOs={getMappedLFOs ? getMappedLFOs(param.id) : []}
            />
          )
        }

        return (
          <div key={param.id} className="flex flex-col gap-1 min-w-[100px]">
            <div className="flex justify-between items-baseline">
              <label className="font-mono text-[9px] tracking-[0.15em] text-white">
                {param.label.toUpperCase()}
              </label>
              <span className="font-mono text-[9px] text-white">
                {formatValue(param.id, (values[param.id] as number) ?? param.default)}
              </span>
            </div>
            <input
              type="range"
              min={param.min}
              max={param.max}
              step={param.step}
              value={(values[param.id] as number) ?? param.default}
              onChange={(e) => onChange(param.id, Number(e.target.value))}
              className="w-full h-[2px] bg-white appearance-none cursor-pointer"
            />
          </div>
        )
      })}
    </div>
  )
}