import * as React from 'react';
import { useKnobTheme } from '../core/theme';

export interface PushButtonProps {
  /** Controlled pressed state. Pair with `onChange`. */
  pressed?: boolean;
  defaultPressed?: boolean;
  onChange?: (pressed: boolean) => void;
  /** 'toggle' latches; 'momentary' is only on while held. Default: 'toggle'. */
  mode?: 'toggle' | 'momentary';
  /** LED / active color. */
  color?: string;
  /** Show the LED strip. Default: true. */
  led?: boolean;
  /** Button height in px. Default: 36. */
  size?: number;
  /** Explicit width; defaults to content. */
  width?: number;
  disabled?: boolean;
  /** Render a hidden form input carrying "on"/"off". */
  name?: string;
  /** Caption, e.g. "MUTE". */
  children?: React.ReactNode;
  className?: string;
  style?: React.CSSProperties;
  'aria-label'?: string;
}

/** Studio panel button with an LED strip — mute/solo/bypass in matching style. */
export const PushButton = React.forwardRef<HTMLButtonElement, PushButtonProps>(
  function PushButton(
    {
      pressed,
      defaultPressed = false,
      onChange,
      mode = 'toggle',
      color,
      led = true,
      size = 36,
      width,
      disabled = false,
      name,
      children,
      className,
      style,
      ...aria
    },
    ref,
  ) {
    const theme = useKnobTheme();
    const accent = color ?? theme.accent ?? '#4cc2ff';
    const isControlled = pressed !== undefined;
    const [internal, setInternal] = React.useState(defaultPressed);
    const [focusVisible, setFocusVisible] = React.useState(false);
    const on = isControlled ? (pressed as boolean) : internal;

    const set = (next: boolean) => {
      if (next === on) return;
      if (!isControlled) setInternal(next);
      onChange?.(next);
    };

    const momentaryProps =
      mode === 'momentary'
        ? {
            onPointerDown: (e: React.PointerEvent) => {
              e.currentTarget.setPointerCapture(e.pointerId);
              set(true);
            },
            onPointerUp: () => set(false),
            onPointerCancel: () => set(false),
            onKeyDown: (e: React.KeyboardEvent) => {
              if ((e.key === ' ' || e.key === 'Enter') && !e.repeat) set(true);
            },
            onKeyUp: (e: React.KeyboardEvent) => {
              if (e.key === ' ' || e.key === 'Enter') set(false);
            },
          }
        : { onClick: () => set(!on) };

    return (
      <button
        ref={ref}
        type="button"
        disabled={disabled}
        aria-pressed={on}
        aria-label={aria['aria-label']}
        data-pressed={on ? '' : undefined}
        data-focus-visible={focusVisible ? '' : undefined}
        className={className}
        onFocus={e => {
          try {
            setFocusVisible(e.currentTarget.matches(':focus-visible'));
          } catch {
            setFocusVisible(true);
          }
        }}
        onBlur={() => setFocusVisible(false)}
        {...momentaryProps}
        style={{
          position: 'relative',
          display: 'inline-flex',
          flexDirection: 'column',
          alignItems: 'center',
          justifyContent: 'center',
          gap: 3,
          height: size,
          width,
          minWidth: size * 1.4,
          padding: '0 12px',
          borderRadius: 7,
          border: '1px solid rgba(0,0,0,0.7)',
          background: on
            ? 'linear-gradient(180deg, #17181d, #232429)'
            : 'linear-gradient(180deg, #35363d, #1d1e24)',
          outline: 'none',
          boxShadow: `${
            on
              ? 'inset 0 2px 5px rgba(0,0,0,0.65)'
              : 'inset 0 1px 0 rgba(255,255,255,0.09), 0 2px 4px rgba(0,0,0,0.45)'
          }${focusVisible ? `, 0 0 0 2px ${theme.focusRing}` : ''}`,
          color: on ? theme.text : theme.label,
          fontFamily: theme.fontUI,
          fontSize: Math.max(10, size * 0.28),
          fontWeight: 600,
          letterSpacing: '0.08em',
          textTransform: 'uppercase',
          cursor: disabled ? 'not-allowed' : 'pointer',
          opacity: disabled ? 0.45 : 1,
          userSelect: 'none',
          WebkitUserSelect: 'none',
          touchAction: 'manipulation',
          transition: 'background 80ms, box-shadow 80ms, color 80ms',
          ...style,
        }}
      >
        {led && (
          <span
            aria-hidden="true"
            style={{
              width: '55%',
              height: Math.max(3, size * 0.09),
              borderRadius: 3,
              background: on ? accent : 'rgba(255,255,255,0.09)',
              boxShadow: on ? `0 0 ${size * 0.22}px ${accent}` : 'inset 0 1px 1px rgba(0,0,0,0.6)',
              transition: 'background 80ms, box-shadow 80ms',
            }}
          />
        )}
        {children}
        {name && <input type="hidden" name={name} value={on ? 'on' : 'off'} readOnly />}
      </button>
    );
  },
);
