<template>
  <div
    v-if="enabled"
    class="config-editor"
  >
    <p
      class="label"
      v-text="template.name"
    />
    <!-- editor -->
    <div
      v-if="template.type === 'object'"
      class="editor"
    >
      <ConfigEditor
        v-for="(prop,key) of template.properties"
        :key="key"
        v-model="config[prop.name]"
        :template="prop"
        :enabled="is_enabled(prop.if)"
      />
    </div>
    <div
      v-else-if="template.type === 'array'"
      class="editor"
    >
      <ConfigEditor
        v-for="(child,key) of config"
        :key="key"
        v-model="config[key]"
        :template="template.child"
        :enabled="is_enabled(template.child.if)"
      />
      <button
        type="button"
        @click="add_item"
      >
        add
      </button>
    </div>
    <div
      v-else-if="template.type === 'string'"
      class="editor"
    >
      <select
        v-if="Array.isArray(template.choices)"
        v-model="config"
      >
        <option
          v-for="(opt,optkey) in template.choices"
          :key="optkey"
          v-text="opt"
        />
      </select>
      <input
        v-else
        v-model="config"
        type="text"
      >
    </div>
    <div
      v-else-if="template.type === 'number'"
      class="editor"
    >
      <input
        v-model="config"
        type="number"
      >
    </div>
    <div
      v-else-if="template.type === 'boolean'"
      class="editor"
    >
      <input
        v-model="config"
        type="checkbox"
      >
    </div>
    <pre v-else>
    invalid config
  </pre>
  </div>
</template>

<script>
import { resolve_data } from '../helper';

export default {
  name:  'ConfigEditor',
  props: {
    // eslint-disable-next-line vue/require-prop-types
    value:    { required: true },
    template: {
      type:     Object,
      required: true,
      enabled:  { type: Boolean, default: true }
    },
    enabled: {
      type:    Boolean,
      default: true
    }
  },
  data () {
    return { temp: this.value };
  },
  computed: {
    config: {
      get () {
        return this.temp;
      },
      set (val) {
        this.$emit ('input', val);
        this.temp = val;
      }
    }
  },
  methods: {
    is_enabled (condition) {
      if (typeof condition === 'undefined')
        return true;
      switch (condition.op) {
        case '=':
          return resolve_data (this.config, condition.prop) === condition.val;
        case '<':
          return resolve_data (this.config, condition.prop) < condition.val;
        case '>':
          return resolve_data (this.config, condition.prop) > condition.val;
        default:
          return false;
      }
    },
    add_item () {
      if (
        typeof this.config === 'undefined'
        || !Array.isArray (this.config)
      )
        this.config = [];
      this.config.push (this.create_default (this.template.child));
    },
    create_default (template) {
      if (typeof template.default !== 'undefined')
        return template.default;
      if (template.type === 'string')
        return '';
      if (template.type === 'number')
        return 0;
      if (template.type === 'boolean')
        return false;
      if (template.type === 'array')
        return [];
      if (template.type === 'object') {
        const res = {};
        for (const prop of template.properties)
          res[prop.name] = this.create_default (prop);
        return res;
      }
      return null;
    }
  }
};
</script>

<style scoped>
.config-editor {
  display: grid;
  grid-template-areas: 'label editor';
  grid-template-columns: auto 1fr;
}

.editor {
  border: 1px solid black;
  margin-left: 10px;
  grid-column: editor;
}

.label {
  display: inline-block;
  grid-column: label;
}
</style>
