<template>
  <figure
    ref="preview"
    :class="{ replaced, cropped }"
    @click="clickHandler"
  >
    <div
      v-if="replaced || cropped"
      class="tooltip-container"
    >
      <div class="tooltip-text">
        {{ tooltipText }}
      </div>
    </div>
    <canvas
      ref="canvas"
      :height="targetHeight"
      :width="targetWidth"
    />
    <ui-icon icon="edit" />
    <span class="folded-corner" />
    <div class="crop-detail">
      <div class="rendition-name">
        {{ renditionName }}
      </div>
      <copy-to-clipboard
        :disabled="replaced"
        :text="previewUrl"
      />
    </div>
  </figure>
</template>
<script>

import { createPreview } from 'Helpers/images';
import { getCropUrl } from 'Helpers/asset';
import CopyToClipboard from 'Components/tools/CopyToClipboard.vue';
import { DEFAULT_ASPECT_RATIO } from 'Config/constants';

const { UiIcon } = window.kiln.utils.components,
  PREVIEW_LINK_HEIGHT = 600;

export default {
  components: {
    CopyToClipboard,
    UiIcon
  },
  props: {
    asset: {
      type: Object,
      default: () => ({})
    },
    aspectRatio: {
      type: String,
      default: DEFAULT_ASPECT_RATIO
    },
    cutout: {
      type: Object,
      default: () => ({})
    },
    renditionName: {
      type: String,
      required: true
    },
    replaced: {
      type: Boolean,
      required: false
    },
    editRendition: {
      type: Function,
      required: true
    },
    renditionKey: {
      type: String,
      default: ''
    },
    referenceName: {
      type: String,
      required: true
    },
    src: {
      type: String,
      required: true
    },
    cropGuide: {
      type: Object,
      validator({ top, left, bottom, right }) {
        return (top >= 0 && top <= 1)
          && (left >= 0 && left <= 1)
          && (bottom >= 0 && bottom <= 1)
          && (right >= 0 && right <= 1);
      },
      default: () => ({})
    },
    previewId: {
      type: Number,
      default: 0
    },
    zoom: {
      type: Boolean,
      default: false
    },
    ignoreMasterCrop: {
      type: Boolean,
      default: false
    },
    masterCrop: {
      type: Object,
      default: () => ({})
    },
    trim: {
      type: Boolean,
      default: false
    },
    height: {
      type: Number,
      required: true
    },
    width: {
      type: Number,
      required: true
    },
    targetWidth: {
      type: Number,
      required: true
    },
    targetHeight: {
      type: Number,
      required: true
    },
    originalDimensions: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    return {
      ctx: null,
      cropped: false,
      defaultRenditionCrop: null
    };
  },
  computed: {
    tooltipText() {
      return Object.values(this.cutout).length
        ? 'Explicit Crop Set'
        : 'Custom rendition override. Delete below to edit.';
    },
    previewUrl() {
      const dimensionProperty = this.trim
        ? { height: PREVIEW_LINK_HEIGHT }
        : { width: this.targetWidth };

      return getCropUrl(this.src, {
        ...dimensionProperty,
        referenceName: this.referenceName,
        renditionKey: this.renditionKey,
        removeOriginalParam: true
      });
    }
  },
  watch: {
    cropGuide() {
      this.draw();
    },
    cutout() {
      this.draw();
    },
    masterCrop() {
      this.draw();
    }
  },
  mounted() {
    this.ctx = this.$refs.canvas.getContext('2d');
    this.draw();
  },
  methods: {
    /**
     * Draws the rendition preview in the canvas
     */
    draw() {
      // we need to update defaultRendition everytime we draw
      this.setDefaultRenditionCrop();

      const img = new Image();

      this.ctx.clearRect(0, 0, this.$refs.canvas.width, this.$refs.canvas.height);

      img.addEventListener('load', () => {
        this.ctx.drawImage(
          img,
          ...this.getDrawingDetails(),
          0, 0, this.targetWidth, this.targetHeight
        );
      });

      img.src = getCropUrl(this.src, {});
    },
    /**
     * Handles click in rendition's preview
     */
    clickHandler() {
      if (!this.replaced) {
        this.editRendition({
          name: this.renditionName,
          aspectRatioString: this.aspectRatio,
          aspectRatio: this.targetWidth / this.targetHeight,
          defaultRenditionCrop: this.defaultRenditionCrop,
          renditionKey: this.renditionKey,
          ignoreMasterCrop: this.ignoreMasterCrop
        });
      }
    },
    /**
     * Obtains drawing details for default rendition
     */
    setDefaultRenditionCrop() {
      const { top, left, height, width } = createPreview(this.originalDimensions, this.asset, {
        rendition: this.renditionKey,
        instruction: this.zoom ? 'zoom' : 'trim',
        width: this.targeWidth,
        height: this.targetHeight,
        ignoreMasterCrop: this.ignoreMasterCrop,
        aspectRatio: this.aspectRatio
      }, true);

      this.defaultRenditionCrop = [left, top, width, height];
    },
    /**
     * Obtains drawing details
     * @returns {number[]} Drawing array object with x, y, width, height values
     */
    getDrawingDetails() {
      this.cropped = false;

      const { top, left, height, width } = createPreview(this.originalDimensions, this.asset, {
        rendition: this.renditionKey,
        instruction: this.zoom ? 'zoom' : 'trim',
        width: this.targeWidth,
        height: this.targetHeight,
        ignoreMasterCrop: this.ignoreMasterCrop,
        aspectRatio: this.aspectRatio
      });

      if (Object.values(this.cutout).length) {
        this.cropped = true;
      }

      return [left, top, width, height];
    }
  }
};
</script>
<style lang="scss" scoped>
  @import 'Styles/colors.scss';

  .crop-detail {
    margin-top: 8px;

    .rendition-name {
      color: $border-color-darker;
      float: left;
      font-size: 14px;
    }
  }

  figure {
    border: 1px solid transparent;
    cursor: pointer;
    padding: 10px;
    position: relative;

    &:hover:not(.replaced) {
      border-color: $item-selected;
      box-shadow: 0 0 6px 1px $border-color;

      .ui-icon.edit {
        display: block;
        text-shadow: 0 0 4px black;
      }
    }

    &.replaced {

      > * {
        opacity: 0.5;
      }

      &:hover {
        cursor: not-allowed;

        .tooltip-container {
          display: block;
          height: 60px;
          opacity: 1;
          top: calc(50% - 48px);

          .tooltip-text {
            height: 45px;
            line-height: 1.15;
            transform: translateY(calc(30px - 50%));
          }
        }
      }
    }

    &.cropped {

      .folded-corner {
        display: block;
      }

      &:hover > .tooltip-container {
        display: block;
        height: 26px;
        opacity: 1;
        top: calc(50% - 28px);

        .tooltip-text {
          height: 18px;
          line-height: normal;
          transform: translateY(calc(13px - 50%));
        }
      }
    }

    .tooltip-container {
      background-color: $border-color-darker;
      border-radius: 2px;
      color: $white;
      display: none;
      font-size: 13px;
      left: 50%;
      transform: translateX(-50%);
      position: absolute;
      text-align: center;
      width: 120px;
      z-index: 1;
    }
  }

  .ui-icon.edit {
    color: $white;
    display: none;
    position: absolute;
    right: 10px;
    top: 10px;
  }

  .folded-corner {
    display: none;
    position: absolute;
    left: 10px;
    top: 10px;
    background-color: $white;
    box-shadow: 2px 2px 2px 0 $disable-color;
    width: 20px;
    height: 20px;

    &::after {
      border-left: 0.5px solid $disable-color;
      content: '';
      height: 27px;
      position: absolute;
      right: -13px;
      top: 6px;
      transform: rotate(45deg);
      width: 27px;
    }
  }
</style>
