import * as React from 'react';
import { Knob } from '../components/Knob';
import { Pointer } from '../primitives/Pointer';
import { Ticks } from '../primitives/Ticks';
import { KnobLabel } from '../primitives/Text';
import { useKnobTheme } from '../core/theme';
import type { SkinProps } from './shared';

export interface SteppedKnobProps extends SkinProps {
  /** Position names, e.g. ['LP','BP','HP']. Sets the number of detents. */
  positions?: readonly string[];
  /** Number of detents when `positions` is not given. */
  steps?: number;
  color?: string;
  tickColor?: string;
  faceColor?: string;
  textColor?: string;
  labelColor?: string;
}

/** Detented selector knob — mode/range switches with hard stops. */
export const SteppedKnob = React.forwardRef<HTMLDivElement, SteppedKnobProps>(function SteppedKnob({
  size = 90,
  positions,
  steps,
  color: colorProp,
  tickColor,
  faceColor = '#1c1d22',
  textColor,
  labelColor,
  label,
  sublabel,
  labelSize,
  showValue = true,
  format,
  focusRing,
  className,
  style,
  ...core
}, ref) {
  const theme = useKnobTheme();
  const color = colorProp ?? theme.accent ?? '#ffd23e';
  const detents = positions ? positions.length : steps ?? 5;
  const min = core.min ?? 0;
  const max = core.max ?? (positions ? positions.length - 1 : 100);

  return (
    <Knob
      ref={ref}
      size={size}
      className={className}
      style={style}
      focusRing={focusRing}
      {...core}
      min={min}
      max={max}
      steps={detents}
      getAriaValueText={core.getAriaValueText ?? (positions ? (v: number) => positions[Math.round(((v - min) / (max - min || 1)) * (detents - 1))] ?? String(v) : format ? (v: number) => format(v) : undefined)}
    >
      {ctx => {
        const index = Math.round(ctx.normalized * (detents - 1));
        return (
          <>
            <Ticks
              count={detents}
              radius={size / 2 - 1}
              length={size * 0.07}
              width={Math.max(1.5, size * 0.022)}
              color={tickColor ?? theme.ticks}
              getTickProps={i => (i === index ? { stroke: color } : undefined)}
            />
            <circle
              cx={ctx.center}
              cy={ctx.center}
              r={size / 2 - size * 0.14}
              fill={faceColor}
              stroke="rgba(255,255,255,0.1)"
              strokeWidth="1"
            />
            <Pointer
              type="triangle"
              radius={size / 2 - size * 0.15}
              length={size * 0.14}
              width={size * 0.09}
              color={color}
            />
            {showValue && (
              <text
                x={ctx.center}
                y={ctx.center}
                textAnchor="middle"
                dominantBaseline="central"
                fontSize={size * (positions ? 0.15 : 0.17)}
                fill={textColor ?? theme.text}
                fontFamily={theme.fontMono}
                fontWeight={600}
                style={{ pointerEvents: 'none' }}
              >
                {positions
                  ? positions[index]
                  : format
                    ? format(ctx.value)
                    : ctx.value.toFixed(ctx.decimals)}
              </text>
            )}
            {label && (
              <KnobLabel
                color={labelColor ?? theme.label}
                fontFamily={theme.fontUI}
                dy={size * 0.45}
                fontSize={labelSize ?? size * 0.095}
                sublabel={sublabel}
              >
                {label}
              </KnobLabel>
            )}
          </>
        );
      }}
    </Knob>
  );
});
