<template>
  <div
    v-bind="$attrs"
    :id="componentId"
    role="radiogroup"
    :class="mergedGroupClass"
  >
    <button
      v-for="site in sites"
      :key="site.id"
      type="button"
      role="radio"
      :aria-checked="activeId === site.id"
      :tabindex="activeId === site.id ? 0 : -1"
      :style="{
        backgroundColor: activeColor,
        opacity: activeId === site.id ? 1 : 0.4,
      }"
      :class="mergedTileClass"
      @click="select(site.id)"
    >
      <span :class="mergedLabelClass">{{ site.name }}</span>
    </button>
  </div>
</template>

<script setup lang="ts">
import {computed, ref, useId} from 'vue'
import {twMerge} from 'tailwind-merge'

defineOptions({name: 'MalioSiteSelector', inheritAttrs: false})

type Site = {
  id: string
  name: string
  color: string
}

const props = withDefaults(defineProps<{
  sites: Site[]
  modelValue?: string
  id?: string
  groupClass?: string
  tileClass?: string
  labelClass?: string
}>(), {
  modelValue: undefined,
  id: '',
  groupClass: '',
  tileClass: '',
  labelClass: '',
})

const emit = defineEmits<{
  (e: 'update:modelValue', value: string): void
  (e: 'change', site: Site): void
}>()

const generatedId = useId()
const componentId = computed(() => props.id || `malio-site-selector-${generatedId}`)

const isControlled = computed(() => props.modelValue !== undefined)
const localValue = ref(props.sites.length > 0 ? props.sites[0]!.id : '')

const activeId = computed(() =>
  isControlled.value ? props.modelValue! : localValue.value,
)

const activeColor = computed(() =>
  props.sites.find((s) => s.id === activeId.value)?.color ?? '',
)

const mergedGroupClass = computed(() =>
  twMerge(
    'flex w-full',
    props.groupClass,
  ),
)

const mergedTileClass = computed(() =>
  twMerge(
    'flex-1 cursor-pointer px-6 py-4 text-center transition-opacity focus:outline-none',
    props.tileClass,
  ),
)

const mergedLabelClass = computed(() =>
  twMerge(
    'text-white font-bold uppercase tracking-wide',
    props.labelClass,
  ),
)

function select(id: string) {
  const site = props.sites.find((s) => s.id === id)
  if (!site) return

  if (!isControlled.value) {
    localValue.value = id
  }
  emit('update:modelValue', id)
  emit('change', site)
}
</script>
