<script lang="ts">
  interface RadioOption {
    value: string;
    label: string;
  }

  interface Props {
    options: RadioOption[];
    selected: string;
    name: string;
    onChange: (value: string) => void;
    disabled?: boolean;
  }

  let { options, selected, name, onChange, disabled = false }: Props = $props();

  function select(value: string) {
    if (disabled) return;
    onChange(value);
  }

  function handleKeydown(e: KeyboardEvent, value: string) {
    if (e.key === ' ' || e.key === 'Enter') {
      e.preventDefault();
      select(value);
    }
  }
</script>

<div class="radio-group" role="radiogroup" aria-label={name}>
  {#each options as opt}
    <label class="radio-item" class:selected={selected === opt.value} class:disabled>
      <button
        class="radio-dot-outer"
        class:selected={selected === opt.value}
        class:disabled
        role="radio"
        aria-checked={selected === opt.value}
        aria-label={opt.label}
        {disabled}
        onclick={() => select(opt.value)}
        onkeydown={e => handleKeydown(e, opt.value)}
      >
        <span class="radio-dot-inner" class:visible={selected === opt.value}></span>
      </button>
      <span class="radio-label">{opt.label}</span>
    </label>
  {/each}
</div>

<style>
  .radio-group {
    display: flex; flex-direction: column; gap: 0.375rem;
  }

  .radio-item {
    display: flex; align-items: center; gap: 0.5rem;
    cursor: pointer; user-select: none;
  }
  .radio-item.disabled { opacity: 0.4; cursor: not-allowed; }

  .radio-dot-outer {
    width: 1rem; height: 1rem; flex-shrink: 0;
    border: 1px solid var(--ctp-surface2); border-radius: 50%;
    background: var(--ctp-surface0); padding: 0;
    cursor: pointer; position: relative;
    display: flex; align-items: center; justify-content: center;
    transition: border-color 0.12s;
  }
  .radio-dot-outer:hover:not(.disabled) { border-color: var(--ctp-blue); }
  .radio-dot-outer:focus-visible { outline: 2px solid var(--ctp-blue); outline-offset: 1px; }
  .radio-dot-outer.selected { border-color: var(--ctp-blue); }
  .radio-dot-outer.disabled { cursor: not-allowed; }

  .radio-dot-inner {
    width: 0.5rem; height: 0.5rem; border-radius: 50%;
    background: var(--ctp-blue);
    opacity: 0; transform: scale(0);
    transition: opacity 0.12s, transform 0.12s;
  }
  .radio-dot-inner.visible { opacity: 1; transform: scale(1); }

  .radio-label {
    font-size: 0.8125rem; color: var(--ctp-text);
  }
</style>
