<template>
  <a-row type="flex">
    <a-col :span="8" style="margin-left: -15px; border-right: 1px solid #e8e8e8">
      <div class="menu">
        <a-button type="link" class="menu-btn" @click="addVNode">{{ $lang('添加节点') }}</a-button>
        <a-button type="link" :disabled="nodes.length < 1" class="menu-btn" @click="delVNode">{{
          $lang('删除')
        }}</a-button>
        <a-button type="link" :disabled="nodes.length < 1" class="menu-btn" icon="up" @click="moveUp">{{
          $lang('上移')
        }}</a-button>
        <a-button type="link" :disabled="nodes.length < 1" class="menu-btn" icon="down" @click="moveDown">{{
          $lang('下移')
        }}</a-button>
      </div>
      <p-steps class="dbStepConfig" direction="vertical">
        <p-step
          v-for="(item, key) in nodes"
          :key="key"
          :title="item.name"
          @click="choseNode(key, item)"
          :status="key == activeIndex ? 'finish' : 'wait'"
          :description="item.description"
        >
          <a-icon slot="icon" type="table" />
        </p-step>
      </p-steps>
    </a-col>
    <a-col :span="16" style="padding: 15px; min-height: 500px">
      <p-grid-form ref="girdForm" formName="setupConfig" :label-col="{ span: 4 }" :wrapper-col="{ span: 16 }">
        <a-tabs default-active-key="1" v-model="tabActive">
          <a-tab-pane v-if="nodes.length > 0" key="1" tab="基础信息">
            <p-grid-form-item
              label="节点ID"
              type="input"
              name="id"
              data-name="id"
              :value="getKeyValue('id', currentNode)"
              @change="handleChange"
            >
            </p-grid-form-item>

            <p-grid-form-item
              label="节点名称"
              type="input"
              name="name"
              :value="getKeyValue('name', currentNode)"
              @change="handleChange"
            >
            </p-grid-form-item>
            <p-grid-form-item
              label="节点顺序"
              type="input"
              name="seq"
              :value="getKeyValue('seq', currentNode)"
              @change="handleChange"
            >
            </p-grid-form-item>
            <p-grid-form-item
              label="节点类型"
              type="select"
              name="type"
              :value="getKeyValue('type', currentNode)"
              :options="[{ value: 'sql', label: 'sql' }]"
              @change="(value) => (currentNode.type = value)"
            >
            </p-grid-form-item>
            <p-grid-form-item
              label="节点打印输出"
              type="select"
              name="nodePrint"
              :value="getKeyValue('nodePrint', currentNode)"
              :options="[
                { value: 'head', label: 'head' },
                { value: 'table', label: 'table' },
                { value: 'update', label: 'update' },
              ]"
              @change="
                (value, label, options, form) => {
                  currentNode.nodePrint = value
                  if (value === 'update') {
                    form.visibleItem('relationNodePrint')
                  } else {
                    form.invisibleItem('relationNodePrint')
                  }
                }
              "
            >
            </p-grid-form-item>
            <p-grid-form-item
              label="关联打印节点"
              type="select"
              name="relationNodePrint"
              :value="getKeyValue('relationNodePrint', currentNode)"
              :invisibleItem="true"
              @change="
                (value) => {
                  currentNode.relationNodePrint = value
                }
              "
              :options="[
                { value: 'head', label: 'head' },
                { value: 'table', label: 'table' },
              ]"
            >
            </p-grid-form-item>

            <p-grid-form-item
              label="描述"
              type="textarea"
              name="description"
              :autoSize="{ minRows: 3, maxRows: 5 }"
              :value="getKeyValue('description', currentNode)"
              @change="(value) => (currentNode.description = value)"
            >
            </p-grid-form-item>
          </a-tab-pane>
          <a-tab-pane v-if="nodes.length > 0" key="2" tab="数据查询" force-render>
            <!-- <p-grid-form-item
              label="数据库"
              type="select"
              name="dbKey"
              autoLoad
              :replaceFields="{ key: 'id', label: 'dsName', value: 'id' }"
              :value="currentNode.dbKey"
              :remoteUrl="{
                url: api.getDataSourceSelect,
              }"
              @change="(value) => (currentNode.dbKey = value)"
            /> -->

            <p-grid-form-item
              label="sql"
              hidden
              type="a-textarea"
              name="data"
              :value="getKeyValue('data', currentNode)"
            />

            <p-grid-form-item label="SQL">
              <PCode
                ref="sqlData"
                style="margin-left: 0; margin-bottom: 10px"
                :height="300"
                v-model="currentNode.data"
                language="sql"
              />
            </p-grid-form-item>
            <p-grid-form-item label="参数">
              <p-table-edit-pro
                v-if="currentNode.params"
                style="margin-bottom: 10px"
                class="table-small"
                size="small"
                ref="paramsTable"
                :pagination="false"
                :showHeader="true"
                :rowSelectType="false"
                :hasRowCount="false"
                :bordered="false"
                rowKey="key"
                :columns="paramsColumn"
                :dataSource.sync="currentNode.params"
              >
                <template slot="operation" slot-scope="text, record">
                  <a-icon
                    @click="delRow"
                    data-value="params"
                    :data-key="record.key"
                    style="font-size: 16px"
                    type="minus-circle"
                  />
                </template>
              </p-table-edit-pro>
            </p-grid-form-item>

            <p-grid-form-item label="扩展字段">
              <a-tabs
                :tabBarGutter="-1"
                size="small"
                v-model="extFieldsActiveKey"
                hide-add
                type="editable-card"
                @edit="onEdit"
              >
                <a-icon style="font-size: 16px" type="plus-circle" slot="tabBarExtraContent" @click="addExtField" />
                <a-tab-pane
                  v-for="(pane, index) in currentNode.extFields"
                  :key="index"
                  :tab="pane.name"
                  :closable="true"
                >
                  <p-grid-form-item
                    label="名称"
                    :wrapperCol="{ span: 16 }"
                    :label-col="{ span: 2 }"
                    type="input"
                    :name="'extFields.name' + index"
                    v-model="pane.name"
                  />
                  <p-grid-form-item
                    :label-col="{ span: 2 }"
                    :wrapper-col="{ span: 16 }"
                    label="脚本"
                    type="a-textarea"
                    :name="'extFields.script' + index"
                    :autoSize="{ minRows: 5 }"
                    v-model="pane.script"
                  />
                </a-tab-pane>
              </a-tabs>
            </p-grid-form-item>
          </a-tab-pane>
          <!-- <a-tab-pane v-if="nodes.length > 0" key="3" tab="数据组装">
            <p-grid-form-item
              label="组装方式"
              name="assemble.type"
              type="select"
              :options="[
                { label: '左连接', value: 'left' },
                { label: '右连接', value: 'right' },
                { label: '全连接', value: 'inner' },
              ]"
              @change="(value) => (currentNode.assemble.type = value)"
              :value="getKeyValue('assemble.type', currentNode)"
            >
            </p-grid-form-item>
            <p-grid-form-item label="关联字段">
              <p-table-edit-pro
                style="margin-bottom: 10px"
                class="table-small"
                size="small"
                ref="assembleTable"
                :pagination="false"
                :showHeader="true"
                :rowSelectType="false"
                :hasRowCount="false"
                :bordered="false"
                rowKey="key"
                :columns="releationsColumn"
                :dataSource.sync="currentNode.assemble.releations"
              >
                <template slot="operation" slot-scope="text, record">
                  <a-icon
                    @click="delRow"
                    data-value="assemble"
                    :data-key="record.key"
                    style="font-size: 16px"
                    type="minus-circle"
                  />
                </template>
              </p-table-edit-pro>
            </p-grid-form-item>
          </a-tab-pane> -->
        </a-tabs>
      </p-grid-form>
    </a-col>
  </a-row>
</template>
<script>
import { getDbkeys, api } from './api'
import PCode from './code'

function createID(length) {
  return Number(Math.random().toString().substr(3, length) + Date.now()).toString(36)
}

function baserParams() {
  return {
    key: createID(),
    name: '',
    value: '',
    type: '',
  }
}
function baserReleations() {
  return {
    key: createID(),
    left: '',
    right: '',
    operator: '',
  }
}
function baseNodeData() {
  return {
    id: '',
    type: '',
    seq: '',
    name: '',
    description: '',
    dbKey: '',
    nodePrint: '',
    relationNodePrint: '',
    data: '',
    extFields: [],
    params: [baserParams()],
    assemble: {
      type: 'left',
      releations: [baserReleations()],
    },
  }
}

export default {
  props: ['conf'],
  components: {
    PCode,
  },
  data() {
    return {
      tabActive: '1',

      api,
      config: {},
      nodes: [],
      getDbkeysOptions: [],
      activeIndex: 0,
      extFieldsActiveKey: 0,
      paramsColumn: [
        { dataIndex: 'name', placeholder: '参数名称', title: '参数名称', type: 'edit' },
        { dataIndex: 'value', placeholder: '参数值', title: '参数值', type: 'edit' },
        {
          dataIndex: 'type',
          placeholder: '参数类型',
          title: '参数类型',
          type: 'select',
          options: [
            { label: '全局参数', value: 'gloabel' },
            { label: '行参数', value: 'line' },
            { label: '常量', value: 'final' },
          ],
        },
        {
          title: () => {
            let _this = this
            return this._c('a-icon', {
              style: 'font-size: 16px',
              attrs: {
                type: 'plus-circle',
                'data-value': 'params',
              },
              on: { click: _this.addRow },
            })
          },
          width: 40,
          align: 'center',
          key: 'operation',
          scopedSlots: { customRender: 'operation' },
        },
      ],
      releationsColumn: [
        { dataIndex: 'left', placeholder: '上一节点字段', title: '上一节点字段', type: 'edit' },
        { dataIndex: 'right', placeholder: '当前节点字段', title: '当前节点字段', type: 'edit' },
        {
          dataIndex: 'operator',
          placeholder: '逻辑操作符',
          title: '逻辑操作符',
          type: 'select',
          options: [
            { label: '并且', value: 'and' },
            { label: '或者', value: 'or' },
          ],
        },
        {
          width: 40,
          align: 'center',
          key: 'operation',
          scopedSlots: { customRender: 'operation' },
          title: () => {
            let _this = this
            return this._c('a-icon', {
              style: 'font-size: 16px',
              attrs: {
                type: 'plus-circle',
                'data-value': 'assemble',
              },
              on: { click: _this.addRow },
            })
          },
        },
      ],
      currentNode: {},
    }
  },
  watch: {
    tabActive(v) {
      if (v == 2) {
        let _this = this
      }
      console.log(v)
    },
    activeIndex(count) {},
    conf(data) {
      try {
        if (!this.conf) {
          this.activeIndex = 0
          this.nodes = []
          this.currentNode = {}

          this.config = {
            id: '',
            name: '',
            fields: {},
            nodes: [],
          }
        } else {
          this.config = JSON.parse(this.conf)
          if (this.config && this.config.nodes) {
            this.config.nodes = this.initNodeData()
            this.nodes = this.config.nodes
            this.activeIndex = 0
            this.currentNode = this.nodes[this.activeIndex]
          }
        }
      } catch (error) {}
    },
    currentNode: {
      handler: (val, oldVal) => {
        // debugger
      },
      deep: true,
    },
  },
  methods: {
    choseNode(index, item) {
      this.activeIndex = index
      this.currentNode = this.nodes[index]

      this.currentNode.assemble.releations = [...this.currentNode.assemble.releations]
      this.currentNode.params = [...this.currentNode.params]
      let values = { ...this.currentNode }
      delete values.assemble
      this.$refs.girdForm.form.setFieldsValue(values)
      if (values.nodePrint == 'update') {
        this.$refs.girdForm.form.visibleItem('relationNodePrint')
      } else {
        this.$refs.girdForm.form.invisibleItem('relationNodePrint')
      }
      if (this.currentNode.extFields.length <= 1) {
        this.extFieldsActiveKey = 0
      }
    },
    getNodeValueByKey(key) {
      return this.getKeyValue(key, this.currentNode)
    },

    getFormValue() {
      this.nodes.forEach((itme) => {
        delete itme['assemble.type']
        delete itme['assemble.releations']
        delete itme['extFields.script']
        delete itme['extFields.name']
        itme.assemble.releations.forEach((itme) => {
          delete itme.key
        })
        itme.params.forEach((itme) => {
          delete itme.key
        })
        if (itme.nodePrint != 'update') {
          itme.relationNodePrint = ''
        }
      })
      this.config.nodes = this.nodes
      return this.config
    },
    getKeyValue(key, obj, type) {
      if (!obj) {
        if (type == 'array') {
          return []
        }
        return ''
      }
      if (obj.nodePrint == 'update') {
        this.$nextTick(() => {
          this.$refs.girdForm.form.visibleItem('relationNodePrint')
        })
      } else {
        this.$nextTick(() => {
          this.$refs.girdForm.form.invisibleItem('relationNodePrint')
        })
      }
      if (key.indexOf('.') > -1) {
        var ob = obj[key.substring(0, key.indexOf('.'))]
        var k = key.substring(key.indexOf('.') + 1)
        return this.getKeyValue(k, ob)
      } else {
        return obj[key]
      }
    },
    addVNode() {
      let i = this.nodes.length
      this.nodes.push({ ...baseNodeData(), name: 'new node-' + i++ })
      this.activeIndex = this.nodes.length - 1
      this.choseNode(this.activeIndex)
      //   this.currentNode = this.nodes[this.activeIndex]
    },
    delVNode() {
      let i = this.activeIndex
      if (this.nodes.length <= 1) {
        this.nodes = []
        this.activeIndex = 0
      } else {
        this.nodes.splice(i, 1)
        if (i > 0) {
          i--
        }
        this.choseNode(i)
      }
    },

    initNodeData() {
      return this.config.nodes.map((itme) => {
        itme = { ...baseNodeData(), ...itme }
        if (itme.assemble.releations.length < 1) {
          itme.assemble.releations = []
        } else {
          itme.assemble.releations = itme.assemble.releations.map((itme) => {
            itme.key = createID()
            return itme
          })
        }
        if (itme.params && itme.params.length < 1) {
          itme.params = []
        } else {
          itme.params = itme.params.map((itme) => {
            itme.key = createID()
            return itme
          })
        }
        return itme
      }, this)
    },
    moveUp() {
      let _i
      if (this.activeIndex < 1) {
        _i = this.nodes.length - 1
      } else {
        _i = this.activeIndex - 1
      }
      let _current = this.nodes[this.activeIndex]
      this.nodes[this.activeIndex] = this.nodes[_i]
      this.nodes[_i] = _current
      this.choseNode(_i)
    },
    moveDown() {
      let _i = this.activeIndex + 1
      if (this.activeIndex >= this.nodes.length - 1) {
        _i = 0
      }
      let _current = this.nodes[this.activeIndex]
      this.nodes[this.activeIndex] = this.nodes[_i]
      this.nodes[_i] = _current
      this.choseNode(_i)
    },
    handleChange(event) {
      if (event) {
        let id = event.target.id.replace('setupConfig_', '')
        this.currentNode[id] = event.target.value
      }
    },
    addRow(event) {
      if (event.currentTarget.disabled) return
      let value = event.currentTarget.dataset.value
      if (value) {
        this.$refs[value + 'Table'].createRow()
      }
    },
    delRow(event) {
      let disabled = event.currentTarget.dataset.disabled
      if (disabled) return
      let value = event.currentTarget.dataset.value
      let key = event.currentTarget.dataset.key
      if (value) {
        this.$refs[value + 'Table'].removeRow(key)
      }
    },
    addExtField() {
      const panes = this.currentNode.extFields
      const activeKey = `NewField${this.currentNode.extFields.length}`
      panes.push({
        name: activeKey,
        script: ``,
      })
      this.extFieldsActiveKey = panes.length - 1
      this.currentNode.extFields = panes
    },
    onEdit(targetKey, action) {
      this[action](targetKey)
    },
    remove(targetKey) {
      let activeKey = this.extFieldsActiveKey
      let lastIndex
      this.currentNode.extFields.forEach((pane, i) => {
        if (i === targetKey) {
          lastIndex = i - 1
        }
      })
      const panes = this.currentNode.extFields
      panes.splice(targetKey, 1)
      if (panes.length) {
        if (lastIndex >= 0) {
          if (activeKey === targetKey) {
            activeKey = lastIndex
          } else {
            activeKey = targetKey
          }
        } else {
          activeKey = 0
        }
      }

      this.currentNode.extFields = panes
      this.extFieldsActiveKey = activeKey
    },
  },
  created() {},
  mounted() {
    let _this = this
    // getDbkeys().then((response) => {
    //   if (response.success)
    //     _this.getDbkeysOptions = response.data.map((item) => {
    //       return { value: item, label: item }
    //     })
    // })

    try {
      if (!this.conf) {
        this.activeIndex = 0
        this.nodes = []
        this.currentNode = { params: [] }

        this.config = {
          id: '',
          name: '',
          fields: {},
          nodes: [],
        }
      } else {
        this.config = JSON.parse(this.conf)
        if (this.config && this.config.nodes) {
          this.config.nodes = this.initNodeData()
          this.nodes = this.config.nodes
          this.activeIndex = 0
          this.currentNode = this.nodes[this.activeIndex]
        }
      }
    } catch (error) {}
  },
}
</script>

<style lang="less">
.dbStepConfig {
  margin: 20px 0px 0px 30px;
  .ant-steps-item:hover {
    cursor: pointer;
  }
}
</style>
<style lang="less" scoped>
/deep/ .ant-tabs-nav .ant-tabs-tab {
  margin: 0;
}
.table-small {
  /deep/ .ant-table-body {
    min-height: auto;
  }
}
.icon-disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.menu {
  //background: #fbfbfb;
}
.menu .menu-btn {
  margin: 5px 0px 5px 10px;
}
</style>
