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

async function submit(...args: any[]) {
  console.debug('submit', `args :>> `, args);
  await new Promise(r => setTimeout(r, 1000))
  alert('Submitted! 🎉')
}

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

onMounted(() => {
  const agreeNode = getNode('agreeNodeId')
  Object.assign(window, { agreeNode })
  console.debug('[onMounted]', `agreeNode :>> `, agreeNode);

  const nameNode = agreeNode?.context?.node.at('attributes.name')
  console.debug('[onMounted]', `nameNode :>> `, nameNode);
  agreeNode!.on('commit', ({ payload }) => {
    console.debug('[agreeNode] [on commit]', `payload :>> `, payload);
    let newValue = (nameNode?.value as string)?.replace(' 👍', '')?.replace(' 👎', '')
    nameNode!.input(`${newValue} ${payload ? '👍' : '👎'}`)
  })
})
</script>

<template>
  <div class="bg-white rounded-xl shadow-xl p-8 mx-auto my-16 max-w-[450px]">

    <FormKit
      type="form"
      #default="{ value }"
      @submit="submit"
      submit-label="提交 ✨"
    >
      <div class="character-attributes">

        <FormKit
          type="group"
          name="attributes"
          id="attributes"
          :validation-rules="{
            validateGroup: (node) => {
              const name = (node.value as Record<string, any>).name
              return name?.includes('测试') ? true : false
            }
          }"
          validation-visibility="live"
          validation="validateGroup"
          :validation-messages="{
  validateGroup: ({ name/* , args */ }) => {
    return `字段 ${name} 必须包含 '测试' 字符串。`
  },
}"
          #default="{ id, messages, fns, classes }"
        >

          <FormKit
            type="text"
            name="name"
            label="姓名"
            help="别人都叫你什么？"
          />
          <div
            v-if="!((value?.attributes as any)?.name)?.includes('测试')"
            class="text-red-500 mb-4 p-2 border border-red-500 rounded"
          >
            输入的姓名必须包含 '测试' 字符串。
          </div>

          <FormKit
            type="checkbox"
            name="flavors"
            label="最喜欢的冰淇淋口味"
            :options="{
              'vanilla': '香草',
              'chocolate': '巧克力',
              'strawberry': '草莓',
            }"
            validation="required|min:2"
          />
          <FormKit
            type="range"
            name="strength"
            id="strength"
            label="Strength"
            value="5"
            validation="min:2|max:9"
            validation-visibility="live"
            min="1"
            max="10"
            step="1"
            help="How many strength points should this character have?"
            :plugins="[castNumber]"
            class="mb-4"
          />


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

      <FormKit
        type="checkbox"
        name="agree"
        id="agreeNodeId"
        label="我同意FormKit是最好的表单开发框架。"
        class="mb-4"
      />
      <pre class="font-mono text-sm p-4 bg-slate-100 mb-4">{{ value }}</pre>

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

<style scoped>
.character-attributes {
  padding: 1.5rem;
  border: 1px solid #e5e7eb;
  border-radius: 0.5rem;
  margin-bottom: 1rem;
  background-color: #f9fafb;
}

.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;
}

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