<template>
  <div class="border border-base-200 rounded-lg bg-base-100" :class="depthPadding">
    <div class="flex items-center justify-between gap-3 px-4 py-3">
      <div class="flex-1">
        <select
          v-model="node.typeComposantId"
          class="select select-bordered select-sm w-full"
          @change="handleComponentTypeSelect(node)"
        >
          <option value="">
            Sélectionner une famille de composant
          </option>
          <option
            v-for="type in componentTypes"
            :key="type.id"
            :value="type.id"
          >
            {{ formatComponentTypeOption(type) }}
          </option>
        </select>
        <p class="mt-1 text-[11px] text-gray-500">
          {{ node.typeComposantId ? `Sélection : ${getComponentTypeLabel(node.typeComposantId) || 'Inconnue'}` : 'Aucune famille sélectionnée' }}
        </p>
      </div>
      <button type="button" class="btn btn-error btn-xs btn-square" @click="emit('remove')">
        <IconLucideTrash class="w-4 h-4" aria-hidden="true" />
      </button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, watch } from 'vue'
import IconLucideTrash from '~icons/lucide/trash'

defineOptions({ name: 'StructureSubComponentEditor' })

type ModelTypeOption = {
  id: string
  name: string
  code?: string | null
}

const props = withDefaults(defineProps<{
  node: Record<string, any>
  depth?: number
  componentTypes?: ModelTypeOption[]
}>(), {
  depth: 0,
  componentTypes: () => [],
})

const emit = defineEmits(['remove'])

const componentTypes = computed(() => props.componentTypes ?? [])

const depthPadding = computed(() => {
  const level = props.depth ?? 0
  return level > 0 ? `ml-${Math.min(level * 4, 12)}` : ''
})

const formatModelTypeOption = (type: ModelTypeOption | undefined | null) => {
  if (!type) {
    return ''
  }
  return type.code ? `${type.name} (${type.code})` : type.name
}

const formatComponentTypeOption = (type: ModelTypeOption | undefined | null) =>
  formatModelTypeOption(type)

const componentTypeMap = computed(() => {
  const map = new Map<string, ModelTypeOption>()
  componentTypes.value.forEach((type) => {
    if (type && typeof type.id === 'string') {
      map.set(type.id, type)
    }
  })
  return map
})

const getComponentTypeLabel = (id?: string) => {
  if (!id) return ''
  return formatModelTypeOption(componentTypeMap.value.get(id))
}

const syncComponentType = (component: any) => {
  if (!component) {
    return
  }
  const id = typeof component.typeComposantId === 'string'
    ? component.typeComposantId
    : ''

  if (!id) {
    component.typeComposantLabel = ''
    component.name = ''
    return
  }

  const option = componentTypeMap.value.get(id)
  if (!option) {
    component.typeComposantLabel = ''
    component.name = ''
    return
  }

  component.typeComposantLabel = formatModelTypeOption(option)
  component.name = option.name || component.typeComposantLabel
}

const handleComponentTypeSelect = (component: any) => {
  syncComponentType(component)
}

watch(componentTypes, () => {
  syncComponentType(props.node)
}, { deep: true, immediate: true })

watch(
  () => props.node.typeComposantId,
  () => {
    syncComponentType(props.node)
  }
)
</script>

<style scoped>
</style>
