<template>
  <div class="min-h-32px bg-#4EB2BF rounded-4px flex items-start pr-4px">
    <div
      class="w-160px text-#fff grid place-items-center shrink-0 py-8px text-center"
      v-if="!actionSchemas.length"
    >
      {{ node.name }}
    </div>

    <div class="flex-1 py-6px">
      <div v-if="isCustomCode" class="w-180px">
        <el-select v-model="methodValue" style="width: 180px" clearable>
          <el-option
            v-for="item in projectStore.project?.methods || []"
            :key="item.id"
            :label="item.name"
            :value="item.id"
          />
        </el-select>
      </div>

      <div v-else-if="actionSchemas.length" class="p-8px w-300px">
        <el-form :model="formData" label-position="left">
          <CusFormItem
            v-for="item in actionSchemas"
            :key="item.field || item.label"
            :schema="item"
            :form-data="formData"
            @change-state-style="handleStateStyleChange"
            @change-collapse="handleReRender"
          />
        </el-form>
      </div>

      <div v-else class="text-white/80 text-12px leading-24px">暂无可编辑内容</div>
    </div>

    <div
      v-if="!isLockedAction"
      class="mx-4px p-2px cursor-pointer self-center"
      @click="emit('delete', node.id)"
    >
      <LuTrash2 size="12px" class="text-accent-red" />
    </div>
  </div>
</template>

<script setup lang="ts">
import type { NodeItemType } from './type'

import { computed, ref, watch } from 'vue'
import { klona } from 'klona'
import { LuTrash2 } from 'vue-icons-plus/lu'

import { useProjectStore } from '@/store/modules/project'
import CusFormItem from '@/views/designer/config/property/CusFormItem.vue'
import { resolveActionDescriptor } from './config'
import MindMap from 'simple-mind-map'

const emit = defineEmits<{
  (e: 'delete', id: string): void
  (e: 'update', node: NodeItemType): void
}>()

const props = defineProps<{
  node: NodeItemType
  mindMap?: MindMap
  mindMapNode: any
}>()

const projectStore = useProjectStore()
const formData = ref<{ payload: any }>({
  payload: klona(props.node.value)
})

const actionMeta = computed(() => props.node.config?.data)
const isCustomCode = computed(() => actionMeta.value?.kind === 'custom_code')
const isLockedAction = computed(
  () =>
    isCustomCode.value ||
    ['builtin.load_page', 'builtin.language_switch', 'builtin.theme_switch'].includes(
      actionMeta.value?.actionData?.actionKey
    )
)

const actionDescriptor = computed(() =>
  resolveActionDescriptor(
    actionMeta.value?.targetData,
    actionMeta.value?.actionData,
    projectStore.project,
    projectStore.activePage?.id
  )
)

const actionSchemas = computed(() => actionDescriptor.value?.schemas || [])

const methodValue = computed({
  get() {
    return props.node.value
  },
  set(val) {
    emit('update', {
      ...props.node,
      value: val
    })
  }
})

const handleReRender = () => {
  setTimeout(() => {
    const changed = props.mindMapNode?.reRender?.([], {
      force: true
    })

    if (changed) {
      props.mindMap?.render(() => {})
    }
  }, 0)
}

watch(
  () => props.node.value,
  (val) => {
    formData.value = {
      payload: klona(val)
    }
  },
  {
    deep: true,
    immediate: true
  }
)

watch(
  () => actionDescriptor.value,
  (descriptor) => {
    if (!descriptor) return
    if (props.node.value !== undefined) return

    const defaultValue = klona(descriptor.defaultValue)
    formData.value = {
      payload: defaultValue
    }

    emit('update', {
      ...props.node,
      value: defaultValue
    })
  },
  {
    immediate: true
  }
)

watch(
  () => formData.value.payload,
  (val) => {
    if (isCustomCode.value) return

    emit('update', {
      ...props.node,
      value: klona(val)
    })
  },
  {
    deep: true
  }
)

const handleStateStyleChange = (_field: string, type: 'add' | 'delete') => {
  if (type === 'delete') {
    emit('delete', props.node.id)
  }
}
</script>

<style lang="less" scoped>
:deep(.el-form-item__label) {
  color: #fff;
}
</style>
