<template>
  <div class="space-y-6">
    <StructureNodeEditor
      :node="localStructure"
      :depth="0"
      :component-types="availableComponentTypes"
      :piece-types="availablePieceTypes"
      is-root
    />
  </div>
</template>

<script setup lang="ts">
import { reactive, watch, computed, onMounted } from 'vue'
import StructureNodeEditor from '~/components/StructureNodeEditor.vue'
import {
  defaultStructure,
  hydrateStructureForEditor,
  cloneStructure,
} from '~/shared/modelUtils'
import { usePieceTypes } from '~/composables/usePieceTypes'
import { useComponentTypes } from '~/composables/useComponentTypes'

defineOptions({ name: 'ComponentModelStructureEditor' })

const props = defineProps({
  modelValue: {
    type: Object,
    default: () => defaultStructure(),
  },
})

const emit = defineEmits(['update:modelValue'])

const localStructure = reactive(hydrateStructureForEditor(props.modelValue))

const syncFromProps = (value: any) => {
  const hydrated = hydrateStructureForEditor(value)
  localStructure.customFields = hydrated.customFields
  localStructure.pieces = hydrated.pieces
  localStructure.subComponents = hydrated.subComponents
  lastEmitted = JSON.stringify(cloneStructure(value))
}

watch(
  () => props.modelValue,
  (value) => {
    syncFromProps(value)
  },
  { deep: true }
)

let lastEmitted = JSON.stringify(cloneStructure(props.modelValue))

watch(
  localStructure,
  (value) => {
    const payload = cloneStructure(value)
    const serialized = JSON.stringify(payload)
    if (serialized !== lastEmitted) {
      lastEmitted = serialized
      emit('update:modelValue', payload)
    }
  },
  { deep: true }
)

const { pieceTypes, loadPieceTypes } = usePieceTypes()
const { componentTypes, loadComponentTypes } = useComponentTypes()

const availablePieceTypes = computed(() => pieceTypes.value ?? [])
const availableComponentTypes = computed(() => componentTypes.value ?? [])

onMounted(async () => {
  const loaders: Promise<any>[] = []
  if (!availablePieceTypes.value.length) {
    loaders.push(loadPieceTypes())
  }
  if (!availableComponentTypes.value.length) {
    loaders.push(loadComponentTypes())
  }
  if (loaders.length) {
    await Promise.allSettled(loaders)
  }
})
</script>
