<template>
  <label
    :class="[
      {'ui-radio--disabled': disabled},
      {'ui-radio--error': error},
    ]"
    class="ui-radio"
  >
    <input
      :name="name"
      :checked="isChecked"
      :value="value"
      class="ui-radio__input _visually-hidden"
      type="radio"
      v-bind="$attrs"
      @change="onChange"
    >
    <span class="ui-radio__check" />
    <span class="ui-radio__label">
      <slot>{{ label }}</slot>
    </span>
    <span
      v-if="$slots.description"
      class="ui-radio__description"
    >
      <slot name="description"/>
    </span>
  </label>
</template>

<script setup lang="ts">
const properties = defineProps<{
  name?: string
  label?: string
  modelValue: string | number | boolean
  value: string | number | boolean
  disabled?: boolean
  error?: boolean
}>();

const emit = defineEmits<{
  (eventName: 'update:modelValue', value: string | number | boolean): void
  (eventName: 'update:error', value: boolean): void
}>();

function onChange() {
  emit('update:modelValue', properties.value);
  if (properties.error) {
    emit('update:error', false);
  }
}

const isChecked = computed(() => properties.modelValue === properties.value);
</script>

<style lang="scss">
.ui-radio {
  display: grid;
  align-items: center;
  column-gap: 8px;
  justify-content: start;

  @media (hover: hover) {
    cursor: pointer;

    &:is(:hover, :focus-visible) {
      opacity: 0.9;
    }
  }
}

.ui-radio__check {
  $size: 16px;

  display: grid;
  place-content: center;
  grid-column: 1;
  grid-row: 1;
  width: $size;
  height: $size;
  border-radius: 50%;
  border: 2px solid $radio-border;
  background-color: $radio-bg;
}

.ui-radio__input:checked ~ .ui-radio__check {
  border-color: $radio-border--checked;
}

.ui-radio__input:checked ~ .ui-radio__check::after {
  $size: 8px;

  content: '';
  width: $size;
  height: $size;
  border-radius: 50%;
  background-color: $radio-bg--checked;
}

.ui-radio__label {
  @include font-md;

  display: flex;
  align-items: center;
  column-gap: 8px;
  grid-column: 2;
  grid-row: 1;
  user-select: none;
  color: var(--radio-text, #{$radio-label});

  @include from-br(sm) {
    @include font-sm;
  }
}

.ui-radio__description {
  @include font-xs;

  font-weight: 400;
  grid-column: 2;
  grid-row: 2;
  user-select: none;
  color: $radio-description;
}

.ui-radio.ui-radio--disabled {
  user-select: none;
  pointer-events: none;
}

.ui-radio.ui-radio--disabled .ui-radio__check {
  border-color: $radio-border--disabled;
}

.ui-radio.ui-radio--disabled .ui-radio__label,
.ui-radio.ui-radio--disabled .ui-radio__description {
  color: $radio-text--disabled;
}

.ui-radio--error.ui-radio .ui-radio__check {
  border-color: $radio-border--error;
}
</style>
