<template>
  <div>
    <field label="Type" v-if="schema.oneOf">
      <!-- Changing type on existing item doesn't work in EF, so field is disabled. See http://stackoverflow.com/questions/3823662/changing-inherited-types-in-entity-framework -->
      <select class="form-control" v-model="valueCopy.$type" :disabled="isNotNew">
        <option v-for="(choice, key) in schema.oneOf" :value="choice.properties.$type.enum[0]" :key="key">{{choice.title}}</option>
      </select>
      <validator :test="!!valueCopy.$type">Kies het type</validator>
    </field>

    <!-- Custom editor (C# CmsItem with CustomEditor attribute) -->
    <component :is="chosenSchema.format" v-if="chosenSchema && chosenSchema.format" v-model="valueCopy" :schema="chosenSchemaProperties"></component>

    <!-- or Default editor -->
    <div v-else>
      <section v-if="(hasGroupedProps && !schema.oneOf) || (hasGroupedProps && schema.oneOf && chosenSchema)">
        <div v-for="(propSchema, propName) in schema.properties" :key="propName">
          <component v-if="propSchema.format && !isSimpleProp(propSchema) && isGroupedProp(propSchema)" :is="propSchema.format" v-model="valueCopy[propName]"
                     :schema="propSchema" :required="!!propSchema.required"></component>

          <schema-component-part v-model="valueCopy[propName]" :schema="propSchema"
                                 v-else-if="!propSchema.isHidden && !isGroupedProp(propSchema)"></schema-component-part>

          <!-- Prop with a reference picker -->
          <schema-field v-else-if="propSchema.$ref" v-model="valueCopy[propName]" :schema="propSchema" :reference="propSchema.$ref"></schema-field>

          <schema-field v-else-if="isGroupedProp(propSchema)" v-model="valueCopy[propName]" :schema="propSchema"></schema-field>
        </div>
      </section>

      <div v-else>
        <div v-for="(propSchema, propName) in schema.properties" :key="propName" v-if="!propSchema.isHidden && !isGroupedProp(propSchema)">
          <schema-component-part v-model="valueCopy[propName]" :schema="propSchema"></schema-component-part>
        </div>
      </div>

      <!-- Editor for when 'oneOf' the 'Type' is chosen -->
      <schema-editor v-model="valueCopy" :schema="chosenSchema" v-if="chosenSchema"></schema-editor>
    </div>
  </div>
</template>

<script>
import { initialValue, isSimpleProp } from './schema-scripts.js';
import { ValueSyncMixin } from '../shared/value-sync-mixin.js';
import * as formElements from '../shared/form/all.js';

export default {
  docs: `Genereert formuliervelden voor een object of pagina op basis van een JSON schema.`,
  name: 'schema-editor',
  mixins: [ValueSyncMixin],
  props: {
    value: {
      type: Object,
      required: true,
    },
    schema: {
      type: Object,
      required: true,
    },
  },
  watch: {
    'valueCopy.$type'() {
      if (this.chosenSchema) {
        var iv = initialValue(this.chosenSchema);
        for (var propName in iv) {
          this.valueCopy[propName] = iv[propName];
        }
      }
    },
  },
  computed: {
    chosenSchema() {
      return (this.schema.oneOf && this.valueCopy)
        ? this.schema.oneOf.find(s => s.properties && s.properties.$type.enum[0] == this.valueCopy.$type)
        : null;
    },
    chosenSchemaProperties() {
      return {
        ...this.schema.properties,
        ...(this.schema.oneOf ? this.chosenSchema.properties : {}),
      };
    },
    hasGroupedProps() {
      return Object.keys(this.schema.properties).some(propName => this.isGroupedProp(this.schema.properties[propName]));
    },
    isNotNew() {
      return this.valueCopy.id;
    },
  },
  methods: {
    isSimpleProp: isSimpleProp,
    isGroupedProp(propSchema) {
      return !propSchema.isHidden && isSimpleProp(propSchema);
    }
  },
  components: {
    ...formElements,
  },
};
</script>
