<template>
  <div class="kyb-json fit">
    <div class="toolbar q-pa-xs">
      <!-- showRight是附加到下面的右侧侧滑面板的模型 -->
      <q-btn
        icon="vertical_align_center"
        title="折叠子项"
        flat
        dense
        size="0.85em"
        @click="openAll=!openAll;openItem(item)"
      >
        <q-tooltip>{{openAll?'展开所有':'折叠所有'}}</q-tooltip>
      </q-btn>
      <q-btn
        v-if="!showonly"
        :icon="isEdit?'lock_open':'lock'"
        :color="isEdit?'primary':'negative'"
        flat
        dense
        size="0.8em"
        @click="isEdit=!isEdit"
      >
        <q-tooltip>{{isEdit?'编辑模式':'只读模式'}}</q-tooltip>
      </q-btn>
      <q-btn
        v-if="isEdit&&!showonly"
        icon="add"
        color="primary"
        flat
        dense
        size="0.85em"
        :disabled="notAdd"
        @click="addItem"
      >
        <q-tooltip>添加子项</q-tooltip>
      </q-btn>
      <q-btn
        v-if="isEdit&&!showonly"
        icon="edit"
        color="primary"
        flat
        dense
        size="0.85em"
        :disabled="notUpdate"
        @click="updateItem"
      >
        <q-tooltip>修改名称</q-tooltip>
      </q-btn>
      <q-btn
        v-if="isEdit&&!showonly"
        icon="clear"
        color="negative"
        flat
        dense
        size="0.85em"
        :disabled="notDel"
        @click="delItem"
      >
        <q-tooltip>删除子项</q-tooltip>
      </q-btn>
    </div>
    <kyb-json-item
      ref="root"
      class="fit scroll"
      :is-edit="isEdit"
      :item="item"
      :item-key="itemKey"
      :tree-selected-item="treeSelectedItem"
      @add-item="$emit('add-item', $event)"
      @select-item="selectItem"
      @del-item="delItem"
      @item-change="itemChange"
    ></kyb-json-item>
  </div>
</template>
<script>
/**
 */
import _ from 'underscore'
import KybJsonItem from './kyb-json-item.vue'
// import { uid } from 'quasar'
let putChild = (value, key, newValue) => {
  if (value) {
    if (_.isObject(value) || _.isArray(value)) {
      newValue.children = []
      _.each(value, (v, k) => {
        let c = {}
        putChild(v, k, c)
        newValue.children.push(c)
      })
    }
  }
  newValue.k = key
  newValue.v = value
  if (_.isString(value)) {
    newValue.type = 'string'
  } else if (_.isNumber(value)) {
    newValue.type = 'number'
  } else if (_.isBoolean(value)) {
    newValue.type = 'boolean'
  } else if (_.isObject(value)) {
    if (_.isArray(value)) {
      newValue.type = 'array'
    } else {
      newValue.type = 'object'
    }
  } else {
    newValue.type = 'other'
  }
}
export default {
  model: {
    prop: 'value',
    event: 'input'
  },
  components: { KybJsonItem },
  props: {
    itemKey: String,
    value: String,
    showonly: Boolean
  },
  data: function() {
    return {
      isEdit: false,
      item: {},
      treeSelectedItem: null,
      keyword: null,
      openAll: false,
      notDel: true,
      notUpdate: true,
      notAdd: true
    }
  },
  watch: {
    'item.name': function(old) {
      // console.log(old);
      this.item.$changeName = old
    },
    value(old) {
      console.log('oooold', old)
      this.fixData(old)
      // this.$forceUpdate();
      this.$refs.root.$forceUpdate()
    }
  },
  created: function() {
    this.fixData(this.value)
  },
  mounted() {
    this.$refs.root.selectItem()
  },
  methods: {
    fixData(value) {
      let v = value || {}
      if (
        _.isString(v) &&
        (value.indexOf('{') === 0 || value.indexOf('[') === 0)
      ) {
        v = JSON.parse(value)
      }
      if (!_.isObject(v)) {
        v = {}
      }
      this.$emit('input', JSON.stringify(v))
      putChild(v, null, this.item)
      // console.log(this.value);
      this.item.lazy = this.lazy
      if (this.item.children && this.item.children.length) {
        this.item.$isOpen = true
      }
    },
    // 递归某一个子节点及子孙显示或隐藏
    openItem: function() {
      this.$refs.root.toggle(this.openAll, true)
      // 当前节点为选中节点
      this.selectItem(this.$refs.root)
    },
    selectItem: function(selectItem) {
      this.notDel = !selectItem.parent
      this.notUpdate =
        !selectItem.parent ||
        selectItem.item.type === 'object' ||
        selectItem.item.type === 'array'
      this.notAdd = false

      this.treeSelectedItem = selectItem
      this.$emit('select-item', selectItem)

      // alert(JSON.stringify(data));
    },
    getNodeByKey: function(key) {
      // TODO 解决查找某个node
    },
    addItem: async function() {
      if (this.treeSelectedItem) {
        console.log(this.treeSelectedItem)
        this.treeSelectedItem.addItem()
        this.$refs.root.$forceUpdate()
        this.$forceUpdate()
        this.$emit('add-item', this.treeSelectedItem)
      }
    },
    itemChange: function(item) {
      console.log('tree', item)
      this.$emit('item-change', item)
      this.$emit('input', JSON.stringify(this.$refs.root.getJSON()))
    },
    updateItem: function(item) {
      this.treeSelectedItem.updateItem()
    },
    delItem: function() {
      if (this.treeSelectedItem) {
        this.treeSelectedItem.delItem()
      }
    }
  }
}
</script>
<style lang="stylus">
.kyb-json {
  position: relative;
  padding-top: 36px;
  overflow: hidden;
}

.kyb-json .toolbar {
  border-bottom: 1px solid $grey-4;
  background: $grey-3;
  height: 36px;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  overflow: hidden;
}

.tree-content {
  overflow: auto;
}

.json-key {
  color: #5f1802;
}

.json-key::after {
  content: ': ';
  color: #5f1802;
}

.edit-key {
  width: 60px;
}

.json-value.string {
  color: #222;
}

.json-value.number {
  color: blue;
}

.json-value.boolean {
  color: #888;
}

.json-value.boolean.true {
  color: #023a21;
}
</style>
