<script>
/* global Flash */
import Visibility from 'visibilityjs';
import Poll from '../../lib/utils/poll';
import eventHub from '../event_hub';
import Service from '../services/index';
import Store from '../stores';
import titleComponent from './title.vue';
import descriptionComponent from './description.vue';
import formComponent from './form.vue';
import '../../lib/utils/url_utility';

export default {
  props: {
    endpoint: {
      required: true,
      type: String,
    },
    canMove: {
      required: true,
      type: Boolean,
    },
    canUpdate: {
      required: true,
      type: Boolean,
    },
    canDestroy: {
      required: true,
      type: Boolean,
    },
    issuableRef: {
      type: String,
      required: true,
    },
    initialTitle: {
      type: String,
      required: true,
    },
    initialDescriptionHtml: {
      type: String,
      required: false,
      default: '',
    },
    initialDescriptionText: {
      type: String,
      required: false,
      default: '',
    },
    isConfidential: {
      type: Boolean,
      required: true,
    },
    markdownPreviewUrl: {
      type: String,
      required: true,
    },
    markdownDocs: {
      type: String,
      required: true,
    },
    projectsAutocompleteUrl: {
      type: String,
      required: true,
    },
  },
  data() {
    const store = new Store({
      titleHtml: this.initialTitle,
      descriptionHtml: this.initialDescriptionHtml,
      descriptionText: this.initialDescriptionText,
    });

    return {
      store,
      state: store.state,
      showForm: false,
    };
  },
  computed: {
    formState() {
      return this.store.formState;
    },
  },
  components: {
    descriptionComponent,
    titleComponent,
    formComponent,
  },
  methods: {
    openForm() {
      if (!this.showForm) {
        this.showForm = true;
        this.store.formState = {
          title: this.state.titleText,
          confidential: this.isConfidential,
          description: this.state.descriptionText,
          move_to_project_id: 0,
        };
      }
    },
    closeForm() {
      this.showForm = false;
    },
    updateIssuable() {
      this.service.updateIssuable(this.store.formState)
        .then(res => res.json())
        .then((data) => {
          if (location.pathname !== data.path) {
            gl.utils.visitUrl(data.path);
          } else if (data.confidential !== this.isConfidential) {
            gl.utils.visitUrl(location.pathname);
          }

          eventHub.$emit('close.form');
        })
        .catch(() => {
          eventHub.$emit('close.form');
          return new Flash('Error updating issue');
        });
    },
    deleteIssuable() {
      this.service.deleteIssuable()
        .then(res => res.json())
        .then((data) => {
          // Stop the poll so we don't get 404's with the issue not existing
          this.poll.stop();

          gl.utils.visitUrl(data.path);
        })
        .catch(() => {
          eventHub.$emit('close.form');
          return new Flash('Error deleting issue');
        });
    },
  },
  created() {
    this.service = new Service(this.endpoint);
    this.poll = new Poll({
      resource: this.service,
      method: 'getData',
      successCallback: (res) => {
        this.store.updateState(res.json());
      },
      errorCallback(err) {
        throw new Error(err);
      },
    });

    if (!Visibility.hidden()) {
      this.poll.makeRequest();
    }

    Visibility.change(() => {
      if (!Visibility.hidden()) {
        this.poll.restart();
      } else {
        this.poll.stop();
      }
    });

    eventHub.$on('delete.issuable', this.deleteIssuable);
    eventHub.$on('update.issuable', this.updateIssuable);
    eventHub.$on('close.form', this.closeForm);
    eventHub.$on('open.form', this.openForm);
  },
  beforeDestroy() {
    eventHub.$off('delete.issuable', this.deleteIssuable);
    eventHub.$off('update.issuable', this.updateIssuable);
    eventHub.$off('close.form', this.closeForm);
    eventHub.$off('open.form', this.openForm);
  },
};
</script>

<template>
  <div>
    <form-component
      v-if="canUpdate && showForm"
      :form-state="formState"
      :can-move="canMove"
      :can-destroy="canDestroy"
      :markdown-docs="markdownDocs"
      :markdown-preview-url="markdownPreviewUrl"
      :projects-autocomplete-url="projectsAutocompleteUrl" />
    <div v-else>
      <title-component
        :issuable-ref="issuableRef"
        :title-html="state.titleHtml"
        :title-text="state.titleText" />
      <description-component
        v-if="state.descriptionHtml"
        :can-update="canUpdate"
        :description-html="state.descriptionHtml"
        :description-text="state.descriptionText"
        :updated-at="state.updatedAt"
        :task-status="state.taskStatus" />
    </div>
  </div>
</template>