<template>
  <label :class="labelClasses" :for="effectiveId">
    <input
      type="radio"
      :id="effectiveId"
      :name="name"
      :value="value"
      :checked="isChecked"
      :disabled="disabled"
      @change="onChange"
    />
    <span class="checkmark radio-mark"></span>
    <span v-if="label" class="radio-text-label">{{ label }}</span>
  </label>
</template>

<script lang="ts">
import { defineComponent, computed, PropType } from 'vue';

export default defineComponent({
  name: 'VRadio',
  props: {
    modelValue: {
      type: [String, Number] as PropType<string | number | null>, // Allow null for when nothing is selected
      required: true,
    },
    value: {
      type: [String, Number] as PropType<string | number>,
      required: true,
    },
    label: {
      type: String,
      default: null,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    id: {
      type: String,
      default: null,
    },
    name: {
      type: String,
      required: true,
    },
  },
  emits: ['update:modelValue'],
  setup(props, { emit }) {
    const effectiveId = computed(() => {
      return props.id || `vradio-${props.name}-${props.value}`;
    });

    const labelClasses = computed(() => [
      'radio-label',
      { 'disabled': props.disabled },
      { 'checked': isChecked.value }, // For potential styling of the label itself when checked
    ]);

    const isChecked = computed(() => {
      return props.modelValue === props.value;
    });

    const onChange = () => {
      if (!props.disabled) {
        emit('update:modelValue', props.value);
      }
    };

    return {
      effectiveId,
      labelClasses,
      isChecked,
      onChange,
    };
  },
});
</script>

<style lang="scss" scoped>
// Styles are very similar to VCheckbox, with adjustments for radio appearance (circle)
.radio-label {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  position: relative;
  user-select: none;
  padding-left: 28px; // Space for the custom radio mark
  min-height: 20px;
  font-size: 1rem;
  margin-right: 10px; // Spacing between radio buttons in a group

  input[type="radio"] {
    position: absolute;
    opacity: 0;
    cursor: pointer;
    height: 0;
    width: 0;
  }

  .checkmark {
    position: absolute;
    top: 50%;
    left: 0;
    transform: translateY(-50%);
    height: 20px;
    width: 20px;
    background-color: #fff;
    border: 1px solid #adb5bd;
    border-radius: 50%; // Makes it a circle for radio
    transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;

    // Radio mark's inner dot (hidden when not checked)
    &.radio-mark:after {
      content: "";
      position: absolute;
      display: none;
      top: 50%;
      left: 50%;
      width: 10px; // Size of the inner dot
      height: 10px;
      border-radius: 50%;
      background: white;
      transform: translate(-50%, -50%);
    }
  }

  input[type="radio"]:checked ~ .checkmark {
    background-color: #007bff;
    border-color: #007bff;
  }

  input[type="radio"]:checked ~ .checkmark.radio-mark:after {
    display: block;
  }

  input[type="radio"]:focus ~ .checkmark {
    box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
  }

  &.disabled {
    cursor: not-allowed;
    opacity: 0.7;

    input[type="radio"]:disabled ~ .checkmark {
      background-color: #e9ecef;
      border-color: #ced4da;
    }

    input[type="radio"]:disabled:checked ~ .checkmark {
      background-color: #7badec; // Lighter primary for disabled checked
      border-color: #7badec;
    }

    input[type="radio"]:disabled:checked ~ .checkmark.radio-mark:after {
      background: #e9ecef; // Match disabled background or a lighter contrast
    }
  }

  .radio-text-label {
    // margin-left: 0.5rem; // Similar to checkbox, handled by padding-left on root
    vertical-align: middle;
  }
}
</style>
