<template>
  <div class="card form-group">
    <header class="card-header">
      <input class="name-input" v-model="valueCopy.name" :readonly="valueCopy.isDefaultVariant" :disabled="valueCopy.isDefaultVariant" />
      <button
        type="button"
        class="btn btn-sm btn-outline-danger vue-delete-button"
        v-if="!valueCopy.isDefaultVariant"
        @click="deleteItem(index)"
      >
        <span aria-hidden="true">&times;</span>
      </button>
    </header>
    <section class="card-body">
      <div class="buttons-container">
        <button type="button" class="btn btn-secondary mr-2" v-if="this.value.isDefaultVariant" @click="handleReset">
          Herstel uitsnede naar standaard
        </button>
      </div>
      <vue-cropper
        ref="cropper"
        :viewMode="1"
        :zoomable="false"
        :autoCropArea="1"
        :responsive="false"
        :data="initialCropData"
        :aspectRatio="valueCopy.fixedAspectRatio"
        :src="asset.imageUrl"
        :cropend="onCrop"
      />
      <input v-if="generatedUrl" type="text" class="form-control" :value="generatedUrl" readonly />
    </section>
  </div>
</template>

<style lang="scss" scoped>
.card-header {
  display: flex;

  input {
    width: 100%;
    font-size: 1.25rem;
  }
}
.card-header h5 {
  flex: 1;
  margin-bottom: 0;
}

.vue-delete-button {
  margin-left: 10px;
}

.buttons-container {
  margin-bottom: 1.25rem;
}
</style>

<script>
import _debounce from 'lodash/debounce';
import VueCropper from 'vue-cropperjs';
import 'cropperjs/dist/cropper.css';
import { ValueSyncMixin } from '../shared/value-sync-mixin.js';
import AssetApi from '../api/asset-api';
import * as assetUtils from '../shared/asset-utils';

// this is hardcoded in the backend at
// https://github.com/Q42/Q.Cms/blob/develop/src/Q.Cms.Core.Api/Controllers/AssetApiController.cs#L119
const PREVIEW_IMAGE_WIDTH = 600;

export default {
  name: 'asset-detail-variant',
  mixins: [ValueSyncMixin],
  props: {
    index: Number,
    asset: Object,
    value: Object
  },
  data() {
    return {
      initialCropData: this.value.crop ? this.scaleOriginalCropToPreviewCrop(this.value.crop) : undefined,
      generatedUrl: null
    };
  },
  methods: {
    scalePreviewCropToOriginalCrop(crop) {
      const cropScale = this.asset.width / Math.min(this.asset.width, PREVIEW_IMAGE_WIDTH);
      return {
        x: Math.floor(crop.x * cropScale),
        y: Math.floor(crop.y * cropScale),
        width: Math.floor(crop.width * cropScale),
        height: Math.floor(crop.height * cropScale)
      };
    },
    scaleOriginalCropToPreviewCrop(crop) {
      const cropScale = this.asset.width / Math.min(this.asset.width, PREVIEW_IMAGE_WIDTH);
      return {
        x: crop.x / cropScale,
        y: crop.y / cropScale,
        width: Math.floor(crop.width / cropScale),
        height: Math.floor(crop.height / cropScale)
      };
    },
    setCropAndCreateUrl() {
      const rawCrop = this.$refs.cropper.getData();
      const crop = this.scalePreviewCropToOriginalCrop(rawCrop);
      this.valueCopy.crop = crop;

      AssetApi.createPublicAssetUrl(this.asset.id, null, null, crop.x, crop.y, crop.width, crop.height).then((res) => {
        this.generatedUrl = res;
      });
    },
    onCrop: _debounce(function () {
      this.setCropAndCreateUrl();
      this.$emit('touched', this.value.id);
    }, 300),
    deleteItem(index) {
      this.$emit('delete', index);
    },
    handleReset() {
      if (!this.value.fixedAspectRatio) {
        return;
      }

      let crop;
      if (this.asset.centerPoint) {
        crop = assetUtils.getCropForAspectRatioForCenterPoint(
          this.asset.width,
          this.asset.height,
          this.value.fixedAspectRatio,
          this.asset.centerPoint
        );
      } else {
        crop = assetUtils.getDefaultCropDataForAspectRatio(this.asset.width, this.asset.height, this.value.fixedAspectRatio);
      }

      this.valueCopy.isUnTouched = true;
      this.valueCopy.crop = crop;
    }
  },
  mounted() {
    const { crop } = this.value;
    if (crop) {
      AssetApi.createPublicAssetUrl(this.asset.id, null, null, crop.x, crop.y, crop.width, crop.height).then((res) => {
        this.generatedUrl = res;
      });
    }
  },
  watch: {
    'value.crop'(newCrop) {
      const crop = this.scaleOriginalCropToPreviewCrop(newCrop);
      this.$refs.cropper.setData(crop);
      AssetApi.createPublicAssetUrl(this.asset.id, null, null, newCrop.x, newCrop.y, newCrop.width, newCrop.height).then((res) => {
        this.generatedUrl = res;
      });
    }
  },
  components: {
    VueCropper
  }
};
</script>
