<template>
  <div>
    <div class="-space-y-px rounded-md bg-white" :class="customWrapperClasses">
      <div
        v-for="(item, index) in items"
        :class="`relative ${
          index != items.length - 1
            ? useIncreasedPadding
              ? 'pb-6'
              : 'pb-4'
            : ''
        } ${
          customClasses ? classes(item, index) : ''
        } first:rounded-t-md last:rounded-b-md`"
        v-bind:key="item[labelName]"
      >
        <div class="flex items-start">
          <input
            type="radio"
            :value="item.value"
            :name="name"
            :id="id"
            v-model="selectedItem"
            @click="onChange(item.value)"
            class="radio-state mt-0.5 h-4 w-4 cursor-pointer disabled:opacity-50"
            :disabled="isDisabled"
            :style="colorStyles"
          />
          <div
            :class="`ml-3 flex cursor-pointer flex-col ${
              isDisabled ? 'opacity-60' : ''
            }`"
            :id="id"
            @click="onChange(item.value)"
          >
            <div class="flex items-center gap-2">
              <p
                class="text-sm font-medium text-gray-900"
                :class="
                  customClasses && item.value === selectedItem
                    ? 'text-indigo-900'
                    : ''
                "
              >
                {{ item[labelName] }}
              </p>
              <c-tag
                v-if="item.tag"
                :label="item.tagLabel"
                :color="item.tagColor"
              ></c-tag>
            </div>
            <p
              class="block text-sm"
              :class="
                customClasses && item.value === selectedItem
                  ? 'text-indigo-700'
                  : 'text-gray-500'
              "
            >
              {{ item.description }}
            </p>
          </div>
        </div>
        <slot v-if="item.value === selectedItem" :name="item.value" />
      </div>
      <div
        v-if="showClearSelection"
        class="cursor-pointer pt-4 text-sm text-gray-400 hover:text-gray-700 hover:underline"
        @click="clearSelection"
      >
        Clear selection
      </div>
    </div>
  </div>
</template>

<script>
import CTag from "../CTag/CTag.vue";
import { COLOR_CONFIG } from "../../colorConfig";

export default {
  name: "CRadio",
  components: { CTag },
  props: {
    id: {
      type: String,
    },
    items: {
      type: Array,
      required: true,
    },
    selectedOption: {
      type: [String, Number, Boolean],
    },
    isDisabled: {
      type: Boolean,
    },
    customClasses: {
      type: Boolean,
      default: false,
    },
    customWrapperClasses: {
      type: String,
    },
    name: {
      type: String,
      required: true,
    },
    labelName: {
      type: String,
      default: "label",
    },
    showClearSelection: {
      type: Boolean,
      default: false,
    },
    useIncreasedPadding: {
      type: Boolean,
      default: false,
    },
    preferredColor: {
      type: String,
      default: "indigo",
    },
  },
  data() {
    return {
      selectedItem: this.selectedOption,
    };
  },
  methods: {
    clearSelection() {
      this.$emit("onChange", null);
      this.selectedItem = null;
    },
    onChange(selectedValue) {
      if (!this.isDisabled) {
        this.$emit("onChange", selectedValue);
        this.selectedItem = selectedValue;
      }
    },
    classes(item, index) {
      let classForRadio = "";
      if (item.value === this.selectedItem && index === 0) {
        classForRadio =
          "border p-4 border-indigo-200 rounded-t-md bg-indigo-50";
      } else if (
        item.value === this.selectedItem &&
        index === this.items.length - 1
      ) {
        classForRadio =
          "border p-4 border-indigo-200 rounded-b-md bg-indigo-50";
      } else if (
        item.value === this.selectedItem &&
        0 < index < this.items.length - 1
      ) {
        classForRadio = "border p-4 border-indigo-200 bg-indigo-50";
      } else {
        classForRadio = "border p-4 border-gray-200";
      }

      return classForRadio;
    },
  },
  computed: {
    colorStyles() {
      const colors = COLOR_CONFIG[this.preferredColor] || COLOR_CONFIG.indigo;
      return {
        "--radio-enabled-color": colors.shade600,
        "--radio-focus-color": colors.shade500,
      };
    },
  },
  watch: {
    selectedOption() {
      this.selectedItem = this.selectedOption;
    },
  },
};
</script>

<style scoped>
/* Unselected state: gray border */
.radio-state {
  border-color: #d1d5db !important;
}
/* Selected state: use theme color for fill and border */
.radio-state:checked {
  color: var(--radio-enabled-color) !important;
  border-color: var(--radio-enabled-color) !important;
}
.radio-state:focus {
  outline: none;
  box-shadow: 0 0 0 2px white, 0 0 0 4px var(--radio-focus-color) !important;
}
</style>
