<script setup lang="ts">
import type { Component } from 'vue'
import Helloworld from '../components/Helloworld.vue'
const count = ref(0)

const compTemplate = computed(() => `
<div class='border'>
    <div>hello i am defined in the setup of app.vue</div>
    <div>This component template is in a computed refreshed on count</div>
    count: <span class="count">${count.value}</span>.
    I dont recommend you to do this for performance issue, prefer passing props for mutable data.
</div>`
)

const ComponentDefinedInSetup = computed(() => h({
  template: compTemplate.value
}) as Component)

const { data, pending } = await useAsyncData('templates', async () => {
  const [interactiveComponent, templateString] = await Promise.all([
    $fetch('/api/full-component'),
    $fetch('/api/template')
  ])

  return {
    interactiveComponent,
    templateString
  }
}, {})

const Interactive = h({
  template: data.value?.interactiveComponent.template,
  setup (props) {
    // eslint-disable-next-line no-new-func
    return new Function(
      'ref',
      'computed',
      'props',
      data.value?.interactiveComponent.setup ?? ''
    )(ref, computed, props)
  },
  props: data.value?.interactiveComponent.props
}) as Component
</script>

<template>
  <!-- Edit this file to play around with Nuxt but never commit changes! -->
  <div>
    <Helloworld id="hello-world" />
    <ComponentDefinedInSetup id="component-defined-in-setup" />
    <button
      id="increment-count"
      @click="count++"
    >
      {{ count }}
    </button>
    <template v-if="!pending">
      <Name
        id="name"
        template="<div>I am the Name.ts component</div>"
      />
      <show-template
        id="show-template"
        :template="data?.templateString ?? ''"
        name="John"
      />
      <Interactive
        id="interactive"
        lastname="Doe"
        firstname="John"
      />
    </template>
  </div>
</template>

<style>
.border {
  border: 1px solid burlywood;
}
</style>