<template>
  <el-form v-if="form" :model="form" ref="formRef" label-width="80px" :rules="formRules">
    <el-form-item label="节点代码">
      <el-input v-model="form.code" readonly />
    </el-form-item>
    <el-form-item label="节点名称" prop="name">
      <el-input v-model="form.name" :readonly="props.mode === 'show'" />
    </el-form-item>
    <el-form-item label="节点类型" prop="type">
      <el-select v-model="form.type" :disabled="props.mode === 'show'">
        <el-option v-for="item in designerStore.nodeTypeList" :key="item.code" :label="item.name" :value="item.code" />
      </el-select>
    </el-form-item>

    <el-form-item label="场景代码" v-if="form.type === 'START' || form.type === 'APPROVE'">
      <el-input v-model="form.seceneCode" :readonly="props.mode === 'show'" />
    </el-form-item>
    <el-form-item label="过期天数" v-if="form.type === 'START' || form.type === 'APPROVE'">
      <el-input v-model.number="form.expireDays" :readonly="props.mode === 'show'" />
    </el-form-item>
    <el-form-item label="选择下步" v-if="form.type === 'START' || form.type === 'APPROVE' || form.type === 'COPY'">
      <el-switch v-model="form.routeOptional" :disabled="props.mode === 'show'" />
    </el-form-item>
    <el-form-item label="分支流程" v-if="form.type === 'BRANCH'" prop="branchCode">
      <el-input v-model="form.branchCode" :readonly="props.mode === 'show'" />
    </el-form-item>
    <el-form-item label="退回节点" v-if="form.type === 'APPROVE'" prop="backCode">
      <el-input v-model="form.backCode" :readonly="props.mode === 'show'" />
    </el-form-item>
    <el-form-item label="保存待办" v-if="form.type === 'APPROVE'">
      <el-switch v-model="form.keepTrace" :disabled="props.mode === 'show'" />
    </el-form-item>
    <el-form-item label="是否返回" v-if="form.type === 'VIRTUAL'">
      <el-switch v-model="form.returnable" :disabled="props.mode === 'show'" />
    </el-form-item>

    <el-form-item label="节点描述">
      <el-input type="textarea" :rows="3" v-model="form.description" :readonly="props.mode === 'show'" />
    </el-form-item>

    <template v-if="form.type === 'APPROVE' || form.type === 'BRANCH'">
      <el-form-item label="结束策略">
        <el-select v-model="form.completeStrategy.strategy" :disabled="props.mode === 'show'">
          <el-option v-for="item in designerStore.strategyList" :key="item.code" :value="item.code"
            :label="item.name" />
        </el-select>
      </el-form-item>
      <el-form-item label="策略计数"
        v-if="form.completeStrategy.strategy === 'COUNT' || form.completeStrategy.strategy === 'PERCENT'">
        <el-input v-model="form.completeStrategy.value" :readonly="props.mode === 'show'" />
      </el-form-item>
    </template>

    <template v-if="form.type === 'START' || form.type === 'APPROVE' || form.type === 'BRANCH' || form.type === 'COPY'">
      <el-form-item label="接收类型">
        <el-select v-model="form.assignment.type" :disabled="props.mode === 'show'">
          <el-option v-for="item in designerStore.assignmentTypeList" :key="item.code" :value="item.code"
            :label="item.name" />
        </el-select>
      </el-form-item>
      <el-form-item label="分支部门" v-if="form.assignment.type === 'BRANCH_DEPT'">
        <el-input v-model="form.assignment.branchDepts" :readonly="props.mode === 'show'" />
      </el-form-item>
      <el-form-item label="部门路径" v-if="form.assignment.type === 'DEPT' || form.assignment?.type === 'ROLE_DEPT'">
        <el-input v-model="form.assignment.deptPaths" :readonly="props.mode === 'show'" />
      </el-form-item>
      <el-form-item label="扩展类名" v-if="form.assignment.type === 'EXTEND'">
        <el-input v-model="form.assignment.className" :readonly="props.mode === 'show'" />
      </el-form-item>
      <el-form-item label="扩展参数" v-if="form.assignment.type === 'EXTEND'">
        <el-input v-model="form.assignment.branchDepts" :readonly="props.mode === 'show'" />
      </el-form-item>
      <el-form-item label="角色代码" v-if="
        form.assignment.type === 'ROLE' ||
        form.assignment.type === 'ROLE_DEPT' ||
        form.assignment.type === 'ROLE_LEVEL'
      ">
        <el-input v-model="form.assignment.roleCode" :readonly="props.mode === 'show'" />
      </el-form-item>
      <el-form-item label="部门层级" v-if="form.assignment.type === 'ROLE_LEVEL'">
        <el-input v-model.number="form.assignment.deptLevel" :readonly="props.mode === 'show'" />
      </el-form-item>
      <el-form-item label="用户路径" v-if="form.assignment.type === 'USER'">
        <el-input v-model="form.assignment.userPaths" :readonly="props.mode === 'show'" />
      </el-form-item>
    </template>
    <div class="cacp-pv-sm cacp-ar"><el-button @click="useOptions.create" type="primary">新增</el-button></div>
    <el-table :data="tableOptions">
      <edit-table-column property="key" label="键" />
      <edit-table-column property="value" label="值" />
      <el-table-column label="操作" width="160" fixed="right">
        <template #default="{ row, $index }">
          <el-button link type="danger" @click="useOptions.del($index)">删除</el-button>
          <template v-if="row.isEdit">
            <el-button link type="primary" @click="useOptions.save($index)">保存</el-button>
            <el-button link @click="useOptions.cancel($index)">取消</el-button>
          </template>
          <template v-else>
            <el-button link type="primary" @click="useOptions.edit($index)">编辑</el-button>
          </template>
        </template>
      </el-table-column>
    </el-table>
    <div class="cacp-pv-sm cacp-ar"><el-button @click="useListeners.create" type="primary">新增</el-button></div>
    <el-table :data="tableListeners">
      <edit-table-column property="key" label="监听器" />
      <el-table-column label="操作" width="160" fixed="right">
        <template #default="{ row, $index }">
          <el-button link type="danger" @click="useListeners.del($index)">删除</el-button>
          <template v-if="row.isEdit">
            <el-button link type="primary" @click="useListeners.save($index)">保存</el-button>
            <el-button link @click="useListeners.cancel($index)">取消</el-button>
          </template>
          <template v-else>
            <el-button link type="primary" @click="useListeners.edit($index)">编辑</el-button>
          </template>
        </template>
      </el-table-column>
    </el-table>
    <!-- options attrs listeners-->
    <el-form-item class="cacp-mt-lg">
      <el-button type="warning" @click="onSave">
        <template #icon>
          <el-icon>
            <Download />
          </el-icon>
        </template>
        保存
      </el-button>
    </el-form-item>
  </el-form>
</template>

<script setup lang="ts">
import { computed, ref, watchEffect } from 'vue'
import { type FormInstance, type FormRules } from 'element-plus'
import { cloneDeep } from 'lodash-es'

import type { OperMode, NodeDescriptor } from '@cacp/ui'

import EditTableColumn from '@/components/editTable'
import { useDesignerStore } from '@/stores'
import type { Graph } from '@antv/x6'
import { useEditTable } from './useEditTable'

const props = defineProps<{
  graph?: Graph
  mode: OperMode
  info?: NodeDescriptor
}>()
const emits = defineEmits<{
  (e: 'on-save', node: NodeDescriptor): void
}>()

const designerStore = useDesignerStore()

const formRules: FormRules = {
  name: [
    {
      required: true,
      message: '名称必填'
    }
  ],
  type: [
    {
      required: true,
      message: '类型必填'
    }
  ],
  backCode: [
    {
      validator: (rule, value, callback) => {
        if (!value || value === '#LAST#') {
          return callback()
        }
        if (!backCodeList.value.some((n) => n.code === value)) {
          return callback('退回环节无效')
        }

        return callback()
      }
    }
  ]
}
const formRef = ref<FormInstance>()
const form = ref<NodeDescriptor>()

const tableListeners = ref<Array<{ key: string; isEdit?: boolean }>>([])
const tableOptions = ref<{
  key: string
  value: unknown
  isEdit?: boolean
}[]>()

const useOptions = useEditTable(tableOptions)
const useListeners = useEditTable(tableListeners)

function getOptions() {
  if (!form.value.options) {
    return []
  }
  return Object.keys(form.value!.options).map((o) => {
    return {
      key: o,
      value: form.value!.options[o]
    }
  })
}

function getListeners() {
  if (!form.value.listeners) {
    return []
  }
  return form.value!.listeners.map((o) => {
    return {
      key: o
    }
  })
}

function writeOptions() {
  form.value.options = tableOptions.value.reduce(
    (pre, v) => {
      pre[v.key] = v.value
      return pre
    },
    {} as Record<string, unknown>
  )
}

function writeListeners() {
  form.value.listeners = tableListeners.value.map((v) => v.key)
}

const backCodeList = computed(() => {
  return props.graph
    .getNodes()
    .map((n) => n.data as NodeDescriptor)
    .filter((n) => n.code !== props.info.code && (n.type === 'START' || n.type === 'APPROVE'))
})

watchEffect(() => {
  form.value = cloneDeep(props.info)
  tableOptions.value = getOptions()
  tableListeners.value = getListeners()
})

function onSave() {
  formRef.value!.validate((valid) => {
    if (valid) {
      writeOptions()
      writeListeners()
      emits('on-save', form.value)
    }
  })
}


</script>
