<script setup lang="ts">
import { FormKitSchemaDefinition, getNode, type FormKitNode } from '@formkit/core';
import { onMounted } from 'vue';
import Guests from './guests.vue';
import Swal from 'sweetalert2'

async function submit(...args: any[]) {
  console.debug('submit', `args :>> `, args);
  await new Promise(r => setTimeout(r, 1000))
  Swal.fire({
    title: 'Submitted! 🎉',
    icon: 'success',
    showConfirmButton: false,
    timer: 1500
  })
}

const castNumber = (node: FormKitNode) => {
  node.hook.input((value, next) => next(Number(value)))
}

onMounted(() => {
  console.group('onMounted')
  const nameNode = getNode('nameNodeId') // 用 id 获取节点
  Object.assign(window, { nameNode })
  console.debug(`nameNode :>> `, nameNode);

  const schemaGroupInput = nameNode?.root.at('schemaGroup.input') // 用路径获取节点
  console.debug(`schemaGroupInput :>> `, schemaGroupInput);
  nameNode?.on('commit', ({ payload }) => {
    console.debug('[nameNode] [on commit]', `payload :>> `, payload);
    schemaGroupInput?.input(`姓名：${payload}`)
  })
  console.groupEnd()
})

const SCHEMA: FormKitSchemaDefinition = [
  {
    $el: 'h1',
    children: [
      {
        $el: 'span',
        children: 'JSON Schema Form',
      },
    ],
    attrs: {
      class: 'font-bold text-2xl mb-4',
      'data-foo': 'bar',
    },
  },
  {
    $formkit: 'group',
    name: 'schemaGroup',
    children: [
      {
        $formkit: 'text',
        label: 'JSON Schema 渲染的输入框',
        name: 'input',
        validation: 'required',
        validationLabel: 'validationLabel', // validation message 使用顺序：validationLabel > label > name
        errors: ['显式设置的错误是非阻塞的，这意味着它们不会像验证错误那样阻止表单提交。您可以在表单文档中了解更多有关错误处理的信息。']
      }
    ]
  }
];

import autoAnimate from "@formkit/auto-animate"
onMounted(() => {
  // setTimeout(() => {
  autoAnimate(document.getElementById('attributes-group-wrapper')!);
  // });
})

</script>

<template>
  <div class="bg-white rounded-xl shadow-xl p-8 mx-auto my-16 max-w-[450px] dark:bg-gray-800 ">
    <h1
      class="font-bold text-2xl mb-4 color:gray-800 dark:text-white"
      data-foo="bar"
    >Tutorial Form</h1>
    <FormKit
      type="form"
      #default="{ value }"
      @submit="submit"
      submit-label="提交 ✨"
    >
      <!-- v-auto-animate -->
      <div
        class="attributes-group"
        id="attributes-group-wrapper"
      >
        <FormKit
          type="group"
          name="attributes"
          :validation-rules="{
            validateGroup: (node) => {
              const name = (node.value as Record<string, any>).name
              return name?.includes('测试') ? true : false
            }
          }"
          validation-visibility="dirty"
          validation="validateGroup"
          :validation-messages="{
            validateGroup: ({ name/* , args */ }) => {
              return `分组 ${name} 下的姓名必须包含 '测试' 字符串。`
            },
          }"
          #default="{ id, messages, fns, classes, value: attributes, }"
        >

          <FormKit
            type="text"
            name="name"
            id="nameNodeId"
            label="姓名"
            :help="`现在 confirmName 的值是：${attributes?.confirmName}`"
            some-attr="some-attr-value"
          >
            <template #label="{ classes, attrs, label, node: nameNode, value }">
              <!-- <pre
                class="font-mono text-sm p-4 bg-slate-100 mb-4">{{ JSON.stringify({ classes, attrs, label }, null, 2) }}</pre> -->
              <label
                for="nameNodeId"
                v-bind="attrs"
                :class="classes.label"
              >{{ label }}<button
                  class="ml-2 px-2 py-1 bg-blue-500 text-white rounded"
                  type="button"
                  @click="
                    !value?.includes('测试')
                      ? nameNode?.input('测试')
                      : nameNode?.input('')"
                >点击{{ value?.includes('测试') ? '清空' : '填充' }}</button>
              </label>
            </template>
          </FormKit>

          <FormKit
            v-if="attributes?.name"
            :preserve="false"
            name="confirmName"
            type="toggle"
            thumb-icon="star"
            :value="true"
            :label="`如果清空 name 输入框，这个确认框及其值将被移除。`"
          />

          <FormKit
            type="checkbox"
            name="flavors"
            label="最喜欢的冰淇淋口味"
            :options="{
              'vanilla': '香草',
              'chocolate': '巧克力',
              'strawberry': '草莓',
            }"
            validation="required|min:2"
          />

          <FormKit
            type="range"
            name="strength"
            label="力量"
            value="5"
            validation="min:2|max:9"
            validation-visibility="live"
            min="1"
            max="10"
            step="1"
            help="这个角色应该有多少力量点？"
            :plugins="[castNumber]"
            class="mb-4"
          />

          <FormKit
            type="textarea"
            auto-height
            label="我有自动高度插件"
            help="这个文本框会随着输入内容增加而增高"
          />

          <!-- By default groups do not show validation messages, so we need to add it manually -->
          <ul
            class="error-box"
            :class="classes.messages"
            v-if="fns.length(messages)"
          >
            <li
              v-for="message in messages"
              :key="message.key"
              :id="`${id}-${message.key}`"
              :data-message-type="message.type"
            >
              {{ message.value }}
            </li>
          </ul>
        </FormKit>
      </div>

      <div class="attributes-group">
        <FormKitSchema :schema="SCHEMA" />
      </div>

      <Guests />

      <FormKit
        type="checkbox"
        name="agree"
        label="我同意FormKit是最好的表单开发框架。"
        class="mb-4"
      />

      <pre class="font-mono text-sm p-4 bg-slate-100 mb-4 dark:bg-gray-900 ">{{ value }}</pre>

    </FormKit>
  </div>
</template>

<style scoped>
ul.error-box {
  padding: 0.75rem;
  border: 1px solid #ef4444;
  border-radius: 0.375rem;
  background-color: #fee2e2;
  color: #b91c1c;
  font-size: 0.875rem;
  line-height: 1.25rem;
}

ul.error-box p {
  font-weight: 500;
}
</style>

<style></style>