<template>
  <div class="card" :class="{ 'border-primary': isOpen && isValid, 'border-danger': !isValid }">
    <header v-if="valueCopy" class="card-header">
      <div v-if="isDraggable" class="vuedraggable-handle mr-2 icon-paragraph-justify"></div>
      <button type="button" class="btn-toggle-page-component mr-2" @click="toggleOpen()" :disabled="!isValid">
        <h5 class="mb-0" :class="{ 'text-danger': !isValid }">
          {{ chosenSchema.title || schema.title }}
          <span :class="[isOpen ? 'icon-arrow-up' : 'icon-arrow-down']"></span>
        </h5>
      </button>
      <img v-if="componentImageUrl" :src="componentImageUrl" />
      <h5 class="mb-0" v-else>{{ componentTitle }}</h5>

      <button v-if="showDeleteButton" @click="deleteComponent" class="btn btn-sm btn-outline-danger vue-delete-button">
        <span aria-hidden="true">&times;</span>
      </button>
    </header>

    <div v-show="isOpen" class="card-body">
      <!-- Custom editor (C# class with CustomEditor attribute) -->
      <component
        :is="chosenSchema.format || schema.format"
        v-if="chosenSchema.format || schema.format"
        v-model="valueCopy"
        :schema="chosenSchemaProperties"
      ></component>

      <!-- or Default editor -->
      <div v-else>
        <template v-for="(propSchema, propName) in chosenSchemaProperties">
          <div :key="propName" v-if="!propSchema.isHidden">
            <!-- Prop with a reference picker -->
            <schema-field
              v-if="isSimpleProp(propSchema) && propSchema.$ref && !propSchema.format"
              v-model="valueCopy[propName]"
              :schema="propSchema"
              :reference="propSchema.$ref"
            ></schema-field>

            <schema-field v-else-if="isSimpleProp(propSchema)" v-model="valueCopy[propName]" :schema="propSchema"></schema-field>
            <schema-component-part v-else v-model="valueCopy[propName]" :schema="propSchema"></schema-component-part>
          </div>
        </template>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.has-draggable-handle {
  position: relative;
}

.btn-toggle-page-component {
  background: 0;
  border: 0;
  color: inherit;
  padding: 0;
}

header {
  display: flex;
  flex-wrap: wrap;
}

img {
  height: 50px;
  margin-top: -9px;
  margin-bottom: -10px;
}

h5 {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  line-height: 31px; // same height as a .btn-sm
}

.vue-delete-button {
  margin-left: auto;
}

.vuedraggable-handle {
  margin-left: -7px;
  cursor: ns-resize;
}
</style>

<script>
import { isSimpleProp, getComponentTitle } from './schema-scripts.js';
import AssetApi from '../api/asset-api';
import { ValueSyncMixin } from '../shared/value-sync-mixin.js';
import validatorGroupBase from '../tools/validator-group-base.vue';
import imagePicker from '../shared/form/image-picker.vue';

export default {
  name: 'schema-page-component',
  docs: `Genereert formuliervelden voor een component op basis van een JSON schema.`,
  extends: validatorGroupBase,
  mixins: [ValueSyncMixin],
  props: {
    value: {
      type: Object,
      required: true
    },
    schema: {
      type: Object,
      required: true
    },
    isDraggable: {
      type: Boolean,
      required: false
    },
    parentIsReadOnly: {
      type: Boolean,
      required: false
    }
  },
  data() {
    return {
      componentImageUrl: null,
      isOpen: !!this.value.isNew
    };
  },
  mounted() {
    this.setComponentImageUrl();
  },
  computed: {
    chosenSchema() {
      return this.schema.oneOf && this.valueCopy
        ? this.schema.oneOf.find((s) => s.properties && s.properties.$type.enum[0] == this.valueCopy.$type)
        : {};
    },
    chosenSchemaProperties() {
      return {
        ...this.schema.properties,
        ...(this.schema.oneOf ? this.chosenSchema.properties : {})
      };
    },
    componentTitle() {
      if (!this.valueCopy) {
        return '';
      }
      return getComponentTitle(this.$store, this.valueCopy, this.chosenSchemaProperties) || '';
    },
    showDeleteButton() {
      return !this.parentIsReadOnly && !this.schema.isReadOnly && (!this.schema.required || this.schema.oneOf);
    },
    isImage() {
      return this.valueCopy && this.valueCopy.$type == 'Q.Cms.Core.Domain.Atoms.Image, Q.Cms.Core.Domain';
    }
  },
  watch: {
    valueCopy: {
      handler() {
        this.setComponentImageUrl();
      },
      deep: true
    },
    isValid(value) {
      if (!value) this.isOpen = true;
    }
  },
  methods: {
    isSimpleProp: isSimpleProp,
    toggleOpen() {
      if (this.isValid) {
        this.isOpen = !this.isOpen;
      }
    },
    async setComponentImageUrl() {
      // only set it for the Image object where id = Guid
      if (this.isImage && this.valueCopy.id) {
        this.componentImageUrl = await AssetApi.getPreviewUrlForAssetId(this.valueCopy.id, this.valueCopy.variantId);
        return;
      }

      this.componentImageUrl = null;
    },
    deleteComponent() {
      this.valueCopy = null;
      this.$emit('deleteComponent');
    }
  },
  components: {
    imagePicker
  }
};
</script>
