<template>
    <div class="node__container" ref="switchRef" @mouseleave="setNodeProperties">
        <NodeState :state="nodeOperatingStatus">
          <template #input>
            <JsonViewer :value="inputJsonData" copyable boxed sort theme="light" />
          </template>
          <template #output>
            <JsonViewer :value="outputJsonData" copyable boxed sort theme="light" />
          </template>
        </NodeState>
        <NodeTitle :icon="switchSvg" :nodeId="props.model.id" :nodeProperties="props.properties" :nodeName="props.properties?.name || '分支'" nodeDesc="连接多个下游分支，根据设定的条件按照顺序查找的方式来匹配运行的分支，如果匹配到某条件则只运行该条件对应的分支，否则继续匹配下一条件直至结束" />
        <div class="condition_title_container">
          <div class="left">
            <div class="space"></div>
            <div class="title">所有条件</div>
          </div>
          <div class="right">
            <el-button :disabled="flowStore.disableForm" @click="addFormItem" class="addFormItem">
              <el-icon :size="20" ><Plus /></el-icon>
            </el-button>
          </div>
        </div>
        <div>
            <el-form :inline="true" :model="formData" :rules="rules" ref="dynamicForm" label-position="top" label-width="auto" :disabled="flowStore.disableForm">
              <div class="condition" v-for="(params, index) in formData.nodeParams" :id="params.id">
                <div class="title__container">
                  <div class="left">
                    <div class="space"></div>
                    <div class="title">{{ index ===0 ? 'If' : 'Else If' }}</div>
                  </div>
                  <div class="right">
                    <el-button :disabled="flowStore.disableForm" circle size="small" @click="deleteFormItem(params.id, index)">
                      <el-icon :size="16" ><Minus /></el-icon>
                    </el-button>
                  </div>
                </div>
                <div class="withOr">
                  <div class="title">条件</div>
                  <div>
                    <el-select v-model="params.withOr" placeholder="Select" style="width: 240px">
                      <el-option key="and" label="AND" value="and" />
                      <el-option key="or" label="OR" value="or" />
                    </el-select>
                  </div>
                </div>
                <div class="form__container">
                  <el-row v-for="(property, pIndex) in params.list">
                  <!--  :prop="`nodeParams.${index}.list.${pIndex}.name`" :rules="[{ required: true, message: '请输入变量名', trigger: 'blur' }]" -->
                    <el-form-item :label="pIndex === 0 ? '引用变量' : ''" :prop="`nodeParams.${index}.list.${pIndex}.nameType`">
                      <!-- <el-input v-model="property.name" placeholder="请输入" clearable /> -->
                      <el-select v-model="property.nameType" @change="handleTypeChange(index, pIndex)">
                        <el-option label="引用" value="quote" />
                        <el-option label="输入" value="input" />
                      </el-select>
                      <el-form-item v-if="property.nameType === 'input'" :rules="[{ required: true, message: '请输入参数值', trigger: 'blur' }]" :prop="`nodeParams.${index}.list.${pIndex}.name`">
                          <el-input v-model="property.name" placeholder="请输入" clearable />
                      </el-form-item>
                      <el-form-item v-if="property.nameType === 'quote'" :rules="[{ required: true, message: '请选择参数值', trigger: 'blur' }]" :prop="`nodeParams.${index}.list.${pIndex}.nameQuote`">
                        <el-cascader v-model="property.nameQuote" :options="quoteOptions" placeholder="请选择" @visible-change="visibleChange" />
                      </el-form-item>
                    </el-form-item>
                    <el-form-item :label="pIndex === 0 ? '选择条件' : ''" :prop="`nodeParams.${index}.list.${pIndex}.condition`" :rules="[{ required: true, message: '请输入变量名', trigger: 'blur' }]">
                      <el-select v-model="property.condition">
                        <el-option label="等于" value="equal" />
                        <el-option label="不等于" value="notEqualTo" />
                        <el-option label="为空" value="null" />
                        <el-option label="不为空" value="notNull" />
                        <el-option label="包含" value="include" />
                        <el-option label="不包含" value="notInclude" />
                        <el-option label="大于" value="greaterThan" />
                        <el-option label="大于等于" value="greaterThanOrEqual" />
                        <el-option label="小于" value="lessThan" />
                        <el-option label="小于等于" value="lessThanOrEqual" />
                      </el-select>
                    </el-form-item>
                    <el-form-item :label="pIndex === 0 ? '比较值' : ''" :prop="`nodeParams.${index}.list.${pIndex}.type`" >
                      <el-select v-model="property.type" @change="handleTypeChange(index, pIndex)">
                        <el-option label="引用" value="quote" />
                        <el-option label="输入" value="input" />
                      </el-select>
                      <el-form-item v-if="property.type === 'input'" :rules="[{ required: true, message: '请输入参数值', trigger: 'blur' }]" :prop="`nodeParams.${index}.list.${pIndex}.input`">
                          <el-input v-model="property.input" placeholder="请输入" clearable />
                      </el-form-item>
                      <el-form-item v-if="property.type === 'quote'" :rules="[{ required: true, message: '请选择参数值', trigger: 'blur' }]" :prop="`nodeParams.${index}.list.${pIndex}.quote`">
                          <el-cascader v-model="property.quote" :options="quoteOptions" placeholder="请选择" @visible-change="visibleChange" />
                      </el-form-item>
                    </el-form-item>
                    <el-form-item :label="pIndex === 0 ? '操作' : ''">
                      <el-button :disabled="flowStore.disableForm" circle size="small" @click="addListItem(index)">
                      <el-icon :size="12" ><Plus /></el-icon>
                    </el-button>
                    <el-button :disabled="flowStore.disableForm" circle size="small" @click="removeListItem(index, pIndex)">
                      <el-icon :size="12" ><Minus /></el-icon>
                    </el-button>
                    </el-form-item>
                    
                  </el-row>
                </div>
              </div>
              </el-form>
        </div>
        <div class="else" :id="''.concat(props.model.id, '_else')">
          <div class="space"></div>
          <div class="title">Else</div>
        </div>
    </div>
</template>
<script setup>
import { nextTick, onMounted, onUnmounted, reactive, ref } from 'vue'
import NodeTitle from '../../components/NodeTitle.vue'
import NodeState from "../../components/NodeState.vue";
import switchSvg from '../../icon/switch.svg'
import { v4 as randomUUID } from 'uuid'
import { useFlowStore } from '@/store/modules/flow'
import { Plus, Minus } from '@element-plus/icons-vue'
import { getInput, addNewEdge, removeSwitchEdge } from '@/utils/flow'
import { emitter } from "@/utils/eventBus";

const props = defineProps({
  model: Object,
  graphModel: Object,
  properties: Object,
  nowTime: Number,
});

const emits = defineEmits(['addAnchor', 'removeAnchor', 'bindRef', 'changeAnchor'])

const switchRef = ref()
const dynamicForm = ref()
const flowStore = useFlowStore()

const formData = reactive({
  nodeParams: props.properties?.conditions || []
})

const addFormItem = () => {
  const rect = switchRef.value.getBoundingClientRect();
  addCondition(rect.height - 60)
}

const deleteFormItem = (id, index) => {
  if (index === 0) {
    return
  }
  formData.nodeParams.splice(index, 1)
  emits('removeAnchor', id)
  removeSwitchEdge(props.model.id, id)
  nextTick(() => {
    changeFormItemHeight()
  })
}

const quoteOptions = ref([])
const handleTypeChange = (pIndex, index) => {
  if (formData.nodeParams[pIndex].list[index].type === 'input') {
    formData.nodeParams[pIndex].list[index].quote = ""
  } else {
    formData.nodeParams[pIndex].list[index].input = ""
    const option = getInput(props.model.id, false)
    if (option) {
      quoteOptions.value = option
    }
  }
}

const addCondition = (height) => {
  const id = randomUUID().replace(/-/g, '')
  formData.nodeParams.push({
    id,
    withOr: 'and',
    list: [{
      name: '',
      nameQuote: '',
      nameType: 'input',
      type: 'input',
      input: '',
      quote: ''
    }]
  })
  emits('addAnchor', height, id)

  setTimeout(() => {
    addNewEdge(props.model.id)
  }, 50)

  nextTick(() => {
    changeFormItemHeight()
  })
}

const addListItem = (pIndex, cIndex) => {
  formData.nodeParams[pIndex].list.push({
    name: '',
    nameQuote: '',
    nameType: 'input',
    type: 'input',
    input: '',
    quote: ''
  })
  nextTick(() => {
    changeFormItemHeight()
  })
}

const removeListItem = (pIndex, cIndex) => {
  if (cIndex === 0) {
    return
  }
  formData.nodeParams[pIndex].list.splice(cIndex, 1)
  nextTick(() => {
    changeFormItemHeight()
  })
}

const changeFormItemHeight = () => {
  formData.nodeParams.forEach(item => {
    const node = document.getElementById(item.id)
    emits('changeAnchor', node.offsetTop, item.id)
  });

  const node = document.getElementById("".concat(props.model.id, "_else"))
  emits('changeAnchor', node.offsetTop, "".concat(props.model.id, "_else"))
}

const setNodeProperties = async () => {
  try {
    const valid = await dynamicForm.value.validate()
    if (valid) {
      const data = toRaw(formData)
      const properties = lf.getProperties(props.model.id)
      lf.setProperties(props.model.id, {
        ...properties,
        ...data
      })
      emits('contentChange')
    }
 } catch (error) {
    dynamicForm.value.clearValidate()
 }
}

const visibleChange = (value) => {
  if (value) {
    const option = getInput(props.model.id)
    if (option) {
        quoteOptions.value = option
    }
  }
}

const nodeOperatingStatus = ref("NORMAL");
const inputJsonData = ref({});
const outputJsonData = ref({});

watch(
  () => props.properties,
  () => {
    if (props.properties.nodeParams && props.properties.nodeParams.length > 0) {
      formData.nodeParams = props.properties.nodeParams
    } else {
        if (formData.nodeParams.length === 0) {
          addCondition(100)
        }
    }
  }, {
    immediate: true,
    deep: true
  }
);

onMounted(() => {
  emits('addAnchor', 280, "".concat(props.model.id, "_else"))

  emits('bindRef', dynamicForm.value)

  emitter.on("changeNodeState", (data) => {
    if (data.nodeId === props.model.id) {
      nodeOperatingStatus.value = data.status;
      let inputData = {};
      let output = {};
      try {
        inputData = JSON.parse(data.paramsIn) || {};
        output = JSON.parse(data.paramsOut) || {};
      } catch (error) {
        inputData = data.paramsIn || {};
        output = data.paramsOut || {};
      }
      inputJsonData.value = inputData;
      outputJsonData.value = output;

      emits("contentChange");
    }
  });

  emitter.on("contentChange", (data) => {
    if (data.id === props.model.id) {
      nodeOperatingStatus.value = "NORMAL";
      inputJsonData.value = {};
      outputJsonData.value = {};

      emits("contentChange");
    }
  });

})

onUnmounted(() => {
  emitter.off("changeNodeState");
  emitter.off("contentChange");
});


</script>
<style lang="scss" scoped>
.node__container {
  width: 720px;
  height: auto;
  background: #fff;
  padding: 12px;
  cursor: default;
  border-radius: 12px;
  border: 2px solid white;
  box-shadow: 0 5px 15px 0#00000008;
  position: relative;

  .condition_title_container {
    display: flex;
    align-items: center;
    justify-content: space-between;

    .left {
      display: flex;
      align-items: center;

      .space {
        width: 4px;
        height: 14px;
        background: rgb(22, 100, 255);
        border-radius: 0px 4px 4px 0px;
      }

      .title {
        margin-left: 8px;
        font-size: 14px;
        font-weight: 500;
      }
    }

    

    .el-button {
      border: none;
    }
  }

  .condition {
    width: 100%;
    height: auto;
    margin-bottom: 10px;
    background-color: #fafbfc;
    padding: 8px 16px;
    border-radius: 8px;
    box-sizing: border-box;

    .title__container {
      display: flex;
      align-items: center;
      justify-content: space-between;

      .left {
        display: flex;
        align-items: center;

        .space {
          width: 4px;
          height: 14px;
          background: rgb(22, 100, 255);
          border-radius: 0px 4px 4px 0px;
        }

        .title {
          margin-left: 8px;
          font-size: 14px;
          font-weight: bold;
        }
      }
    }

    .withOr {
      margin-bottom: 12px;

      .title {
        font-size: 14px;
        color: #737a87;
        margin-bottom: 4px;
      }
    }

    :deep(.form__container) {

      .el-form-item {
        margin-right: 20px;
      }

      .el-input {
        width: 92px;
      }

      .el-select {
        width: 92px;
      }

      .el-cascader {
        width: 92px;
      }
    }
  }

  .else {
    display: flex;
    align-items: center;
    background-color: #fafbfc;
    padding: 8px 16px;

    .space {
        width: 4px;
        height: 14px;
        background: rgb(22, 100, 255);
        border-radius: 0px 4px 4px 0px;
      }

      .title {
        margin-left: 8px;
        font-size: 14px;
        font-weight: 500;
        font-weight: bold;
      }
  }
}
</style>