<template>
  <div class="cpRadioGroup" :class="cpRadioGroupDynamicClasses">
    <div v-if="hasGroupHeader" class="cpRadioGroup__header">
      <span v-if="groupLabel" :id="radioGroupLabelId" class="cpRadioGroup__label">
        {{ groupLabel }}
        <span v-if="required" class="cpRadioGroup__required">*</span>
        <span v-else class="cpRadioGroup__optional">(Optional)</span>
      </span>
      <span v-if="groupHelperText" :id="radioGroupHelperTextId" class="cpRadioGroup__helperText">{{
        groupHelperText
      }}</span>
    </div>
    <div class="cpRadioGroup__options">
      <cp-radio-new v-for="option in options" :key="option.value" :option="option" />
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, provide, reactive, toRef, useId } from 'vue'

import { capitalizeFirstLetter } from '@/helpers'
import CpRadioNew, { type RadioOption } from './CpRadioNew.vue'

interface Props {
  autofocus?: boolean
  direction?: 'horizontal' | 'vertical'
  groupHelperText?: string
  groupLabel?: string
  groupName?: string
  modelValue: string
  options: RadioOption[]
  required?: boolean
  size?: 'md' | 'lg'
}

interface Emits {
  (e: 'update:modelValue', value: string): void
}

const props = withDefaults(defineProps<Props>(), {
  groupName: '',
  autofocus: false,
  direction: 'vertical',
  groupLabel: '',
  groupHelperText: '',
  size: 'md',
})

const emit = defineEmits<Emits>()

const radioGroudId = useId()
const radioGroupLabelId = useId()
const radioGroupHelperTextId = useId()

const onChange = (value: string): void => emit('update:modelValue', value)

const cpRadioGroupDynamicClasses = computed(() => [
  `cpRadioGroup--${props.size}`,
  `cpRadioGroup--is${capitalizeFirstLetter(props.direction)}`,
])
const hasGroupHeader = computed(() => props.groupLabel || props.groupHelperText)
const hasOptionRequiredVisible = computed(() => props.required && !props.groupLabel)
const hasOptionNotRequiredVisible = computed(() => !props.required && !props.groupLabel)

provide(
  'radioGroup',
  reactive({
    autofocus: toRef(props, 'autofocus'),
    groupName: toRef(props, 'groupName'),
    modelValue: toRef(props, 'modelValue'),
    onChange,
    radioGroupHelperTextId,
    radioGroupLabelId,
    showOptional: hasOptionNotRequiredVisible,
    showRequired: hasOptionRequiredVisible,
    size: toRef(props, 'size'),
    radioGroudId,
  }),
)
</script>

<style lang="scss">
.cpRadioGroup {
  display: flex;
  width: 100%;
  flex-direction: column;
  gap: var(--cp-spacing-md);

  &__options {
    display: flex;
    flex-direction: column;
    gap: var(--cp-spacing-md);
  }

  &--isHorizontal .cpRadioGroup__options {
    flex-flow: row wrap;
    align-items: flex-start;
    gap: var(--cp-spacing-2xl);
  }

  &__header {
    display: flex;
    flex-direction: column;
    font-family: Figtree, sans-serif;
    font-size: var(--cp-text-size-sm);
    line-height: var(--cp-line-height-sm);
  }

  &--lg .cpRadioGroup__header {
    font-size: var(--cp-text-size-md);
    line-height: var(--cp-line-height-md);
  }

  &__label {
    display: flex;
    align-items: baseline;
    color: var(--cp-text-primary);
    font-weight: 500;
    gap: var(--cp-spacing-sm);
  }

  &__helperText {
    color: var(--cp-text-secondary);
    font-weight: 400;
  }

  &__required {
    color: var(--cp-text-error-primary);
    font-weight: 700;
  }

  &__optional {
    color: var(--cp-text-secondary);
    font-size: var(--cp-text-size-xs);
    font-weight: 400;
    line-height: var(--cp-line-height-xs);
  }

  &--lg &__optional {
    font-size: var(--cp-text-size-sm);
    line-height: var(--cp-line-height-sm);
  }
}
</style>
