/* global React */
/**
 * Toggle — pill switch component
 *
 * Props:
 *   checked        boolean          controlled on/off
 *   defaultChecked boolean          uncontrolled initial
 *   onChange       (next) => void
 *   disabled       boolean
 *   size           "sm" | "md" | "lg"   default "md"
 *   label          node             right-side label
 *   description    node             sub-label under label
 *   id             string
 *   name           string           hidden form field name
 *   tone           "highlight" | "primary" | "copilot"
 */

const TOGGLE_SIZES = {
  sm: { track: [24, 10], knob: 14, pad: -2, travel: 14 },
  md: { track: [28, 12], knob: 16, pad: -2, travel: 16 },
  lg: { track: [36, 16], knob: 20, pad: -2, travel: 20 },
};

const TOGGLE_TONES = {
  highlight: {
    on: 'var(--highlight-500, #6C40E5)',
    onHover: 'var(--highlight-600, #5F30D1)',
    focusRing: 'rgba(108, 64, 229, 0.28)',
  },
  primary: {
    on: 'var(--primary-500, #1E9B54)',
    onHover: 'var(--primary-600, #1B7A45)',
    focusRing: 'rgba(30, 155, 84, 0.28)',
  },
  copilot: {
    on: 'var(--copilot-600, #9216DA)',
    onHover: 'var(--copilot-700, #7B18B1)',
    focusRing: 'rgba(146, 22, 218, 0.32)',
  },
};

function Toggle({
  checked,
  defaultChecked = false,
  onChange,
  disabled = false,
  size = 'md',
  label,
  description,
  id,
  name,
  tone = 'highlight',
  className = '',
  style,
}) {
  const isControlled = checked !== undefined;
  const [internal, setInternal] = React.useState(defaultChecked);
  const isOn = isControlled ? checked : internal;

  const reactId = React.useId ? React.useId() : undefined;
  const switchId = id || reactId || `toggle-${name || 'x'}`;

  const dims = TOGGLE_SIZES[size] || TOGGLE_SIZES.md;
  const toneVars = TOGGLE_TONES[tone] || TOGGLE_TONES.highlight;
  const [trackW, trackH] = dims.track;

  const toggle = () => {
    if (disabled) return;
    const next = !isOn;
    if (!isControlled) setInternal(next);
    onChange?.(next);
  };

  const onKey = (e) => {
    if (disabled) return;
    if (e.key === ' ' || e.key === 'Enter') {
      e.preventDefault();
      toggle();
    }
  };

  const trackStyle = {
    '--ff-tgl-w': `${trackW}px`,
    '--ff-tgl-h': `${trackH}px`,
    '--ff-tgl-knob': `${dims.knob}px`,
    '--ff-tgl-pad': `${dims.pad}px`,
    '--ff-tgl-travel': `${dims.travel}px`,
    '--ff-tgl-on': toneVars.on,
    '--ff-tgl-on-hover': toneVars.onHover,
    '--ff-tgl-focus': toneVars.focusRing,
  };

  const hasText = !!(label || description);

  const switchBtn = (
    <button
      id={switchId}
      type="button"
      role="switch"
      aria-checked={isOn}
      aria-disabled={disabled || undefined}
      aria-labelledby={hasText ? `${switchId}-lbl` : undefined}
      disabled={disabled}
      onClick={toggle}
      onKeyDown={onKey}
      className="ff-toggle__track"
      style={trackStyle}
    >
      <span className="ff-toggle__knob" aria-hidden="true" />
    </button>
  );

  const hiddenField = name ? (
    <input type="hidden" name={name} value={isOn ? 'on' : 'off'} />
  ) : null;

  if (!hasText) {
    return (
      <span
        className={`ff-toggle ff-toggle--${size} ${disabled ? 'is-disabled' : ''} ${className}`}
        style={style}
        data-state={isOn ? 'on' : 'off'}
      >
        {switchBtn}
        {hiddenField}
      </span>
    );
  }

  return (
    <span
      className={`ff-toggle ff-toggle--${size} ${disabled ? 'is-disabled' : ''} ${className}`}
      style={style}
      data-state={isOn ? 'on' : 'off'}
    >
      {switchBtn}
      {hiddenField}
      <label
        htmlFor={switchId}
        id={`${switchId}-lbl`}
        className="ff-toggle__text"
      >
        {label && <span className="ff-toggle__label">{label}</span>}
        {description && <span className="ff-toggle__desc">{description}</span>}
      </label>
    </span>
  );
}

window.Toggle = Toggle;
