<script>
import { GlPopover, GlButton, GlTooltipDirective } from '@gitlab/ui';
import $ from 'jquery';
import { keysFor, BOLD_TEXT, ITALIC_TEXT, LINK_TEXT } from '~/behaviors/shortcuts/keybindings';
import { getSelectedFragment } from '~/lib/utils/common_utils';
import { s__ } from '~/locale';
import { CopyAsGFM } from '../../../behaviors/markdown/copy_as_gfm';
import ToolbarButton from './toolbar_button.vue';

export default {
  components: {
    ToolbarButton,
    GlPopover,
    GlButton,
  },
  directives: {
    GlTooltip: GlTooltipDirective,
  },
  props: {
    previewMarkdown: {
      type: Boolean,
      required: true,
    },
    lineContent: {
      type: String,
      required: false,
      default: '',
    },
    canSuggest: {
      type: Boolean,
      required: false,
      default: true,
    },
    showSuggestPopover: {
      type: Boolean,
      required: false,
      default: false,
    },
    suggestionStartIndex: {
      type: Number,
      required: false,
      default: 0,
    },
  },
  data() {
    return {
      tag: '> ',
      suggestPopoverVisible: false,
    };
  },
  computed: {
    mdTable() {
      return [
        // False positive i18n lint: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/26
        '| header | header |', // eslint-disable-line @gitlab/require-i18n-strings
        '| ------ | ------ |',
        '| cell | cell |', // eslint-disable-line @gitlab/require-i18n-strings
        '| cell | cell |', // eslint-disable-line @gitlab/require-i18n-strings
      ].join('\n');
    },
    mdSuggestion() {
      return [['```', `suggestion:-${this.suggestionStartIndex}+0`].join(''), `{text}`, '```'].join(
        '\n',
      );
    },
    mdCollapsibleSection() {
      return ['<details><summary>Click to expand</summary>', `{text}`, '</details>'].join('\n');
    },
    isMac() {
      // Accessing properties using ?. to allow tests to use
      // this component without setting up window.gl.client.
      // In production, window.gl.client should always be present.
      return Boolean(window.gl?.client?.isMac);
    },
    modifierKey() {
      return this.isMac ? '⌘' : s__('KeyboardKey|Ctrl+');
    },
  },
  watch: {
    showSuggestPopover() {
      this.updateSuggestPopoverVisibility();
    },
  },
  mounted() {
    $(document).on('markdown-preview:show.vue', this.previewMarkdownTab);
    $(document).on('markdown-preview:hide.vue', this.writeMarkdownTab);

    this.updateSuggestPopoverVisibility();
  },
  beforeDestroy() {
    $(document).off('markdown-preview:show.vue', this.previewMarkdownTab);
    $(document).off('markdown-preview:hide.vue', this.writeMarkdownTab);
  },
  methods: {
    async updateSuggestPopoverVisibility() {
      await this.$nextTick();

      this.suggestPopoverVisible = this.showSuggestPopover && this.canSuggest;
    },
    isValid(form) {
      return (
        !form ||
        (form.find('.js-vue-markdown-field').length && $(this.$el).closest('form')[0] === form[0])
      );
    },

    previewMarkdownTab(event, form) {
      if (event.target.blur) event.target.blur();
      if (!this.isValid(form)) return;

      this.$emit('preview-markdown');
    },

    writeMarkdownTab(event, form) {
      if (event.target.blur) event.target.blur();
      if (!this.isValid(form)) return;

      this.$emit('write-markdown');
    },
    handleSuggestDismissed() {
      this.$emit('handleSuggestDismissed');
    },
    handleQuote() {
      const documentFragment = getSelectedFragment();

      if (!documentFragment || !documentFragment.textContent) {
        this.tag = '> ';
        return;
      }
      this.tag = '';

      const transformed = CopyAsGFM.transformGFMSelection(documentFragment);
      const area = this.$el.parentNode.querySelector('textarea');

      CopyAsGFM.nodeToGFM(transformed)
        .then((gfm) => {
          CopyAsGFM.insertPastedText(area, documentFragment.textContent, CopyAsGFM.quoted(gfm));
        })
        .catch(() => {});
    },
  },
  shortcuts: {
    bold: keysFor(BOLD_TEXT),
    italic: keysFor(ITALIC_TEXT),
    link: keysFor(LINK_TEXT),
  },
};
</script>

<template>
  <div class="md-header">
    <ul class="nav-links clearfix">
      <li :class="{ active: !previewMarkdown }" class="md-header-tab">
        <button class="js-write-link" type="button" @click="writeMarkdownTab($event)">
          {{ __('Write') }}
        </button>
      </li>
      <li :class="{ active: previewMarkdown }" class="md-header-tab">
        <button
          class="js-preview-link js-md-preview-button"
          type="button"
          @click="previewMarkdownTab($event)"
        >
          {{ __('Preview') }}
        </button>
      </li>
      <li :class="{ active: !previewMarkdown }" class="md-header-toolbar">
        <toolbar-button
          tag="**"
          :button-title="
            sprintf(s__('MarkdownEditor|Add bold text (%{modifierKey}B)'), { modifierKey })
          "
          :shortcuts="$options.shortcuts.bold"
          icon="bold"
        />
        <toolbar-button
          tag="_"
          :button-title="
            sprintf(s__('MarkdownEditor|Add italic text (%{modifierKey}I)'), { modifierKey })
          "
          :shortcuts="$options.shortcuts.italic"
          icon="italic"
        />
        <toolbar-button
          :prepend="true"
          :tag="tag"
          :button-title="__('Insert a quote')"
          icon="quote"
          @click="handleQuote"
        />
        <template v-if="canSuggest">
          <toolbar-button
            ref="suggestButton"
            :tag="mdSuggestion"
            :prepend="true"
            :button-title="__('Insert suggestion')"
            :cursor-offset="4"
            :tag-content="lineContent"
            icon="doc-code"
            data-qa-selector="suggestion_button"
            class="js-suggestion-btn"
            @click="handleSuggestDismissed"
          />
          <gl-popover
            v-if="suggestPopoverVisible"
            :target="$refs.suggestButton.$el"
            :css-classes="['diff-suggest-popover']"
            placement="bottom"
            :show="suggestPopoverVisible"
          >
            <strong>{{ __('New! Suggest changes directly') }}</strong>
            <p class="mb-2">
              {{
                __(
                  'Suggest code changes which can be immediately applied in one click. Try it out!',
                )
              }}
            </p>
            <gl-button
              variant="info"
              category="primary"
              size="small"
              @click="handleSuggestDismissed"
            >
              {{ __('Got it') }}
            </gl-button>
          </gl-popover>
        </template>
        <toolbar-button tag="`" tag-block="```" :button-title="__('Insert code')" icon="code" />
        <toolbar-button
          tag="[{text}](url)"
          tag-select="url"
          :button-title="
            sprintf(s__('MarkdownEditor|Add a link (%{modifierKey}K)'), { modifierKey })
          "
          :shortcuts="$options.shortcuts.link"
          icon="link"
        />
        <toolbar-button
          :prepend="true"
          tag="- "
          :button-title="__('Add a bullet list')"
          icon="list-bulleted"
        />
        <toolbar-button
          :prepend="true"
          tag="1. "
          :button-title="__('Add a numbered list')"
          icon="list-numbered"
        />
        <toolbar-button
          :prepend="true"
          tag="- [ ] "
          :button-title="__('Add a task list')"
          icon="list-task"
        />
        <toolbar-button
          :tag="mdCollapsibleSection"
          :prepend="true"
          tag-select="Click to expand"
          :button-title="__('Add a collapsible section')"
          icon="details-block"
        />
        <toolbar-button
          :tag="mdTable"
          :prepend="true"
          :button-title="__('Add a table')"
          icon="table"
        />
        <toolbar-button
          class="js-zen-enter"
          :prepend="true"
          :button-title="__('Go full screen')"
          icon="maximize"
        />
      </li>
    </ul>
  </div>
</template>
