import GlIcon from '../../../../../base/icon/icon';
import GlLoadingIcon from '../../../../../base/loading_icon/loading_icon';
import { GlTooltipDirective } from '../../../../../../directives/tooltip';
import GlDuoChatContextItemSelections from '../duo_chat_context/duo_chat_context_item_selections/duo_chat_context_item_selections';
import GlDuoUserFeedback from '../../../user_feedback/user_feedback';
import GlFormGroup from '../../../../../base/form/form_group/form_group';
import GlFormTextarea from '../../../../../base/form/form_textarea/form_textarea';
import { SafeHtmlDirective } from '../../../../../../directives/safe_html/safe_html';
import { SELECTED_CONTEXT_ITEMS_DEFAULT_COLLAPSED, MESSAGE_MODEL_ROLES } from '../../constants';
import { translate, translatePlural, sprintf } from '../../../../../../utils/i18n';
import DocumentationSources from '../duo_chat_message_sources/duo_chat_message_sources';
import { renderDuoChatMarkdownPreview } from '../../markdown_renderer';
import { CopyCodeElement } from './copy_code_element';
import { InsertCodeSnippetElement } from './insert_code_snippet_element';
import { concatUntilEmpty } from './utils';
import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';

const i18n = {
  MODAL: {
    TITLE: translate('GlDuoChatMessage.modalTitle', 'Give feedback on GitLab Duo Chat'),
    ALERT_TEXT: translate('GlDuoChatMessage.modalAlertText', 'GitLab team members cannot view your conversation. Please be as descriptive as possible.'),
    DID_WHAT: translate('GlDuoChatMessage.modalDidWhat', 'What were you doing?'),
    INTERACTION: translate('GlDuoChatMessage.modalInteraction', 'The situation in which you interacted with GitLab Duo Chat.'),
    IMPROVE_WHAT: translate('GlDuoChatMessage.modalImproveWhat', 'How could the response be improved?'),
    BETTER_RESPONSE: translate('GlDuoChatMessage.modalBetterResponse', 'How the response might better meet your needs.'),
    MESSAGE_ERROR: translate('GlDuoChatMessage.modalMessageError', 'Error sending the message')
  }
};
var script = {
  name: 'GlDuoChatMessage',
  i18n,
  safeHtmlConfigExtension: {
    ADD_TAGS: ['copy-code', 'insert-code-snippet']
  },
  components: {
    DocumentationSources,
    GlDuoChatContextItemSelections,
    GlDuoUserFeedback,
    GlFormGroup,
    GlFormTextarea,
    GlIcon,
    GlLoadingIcon
  },
  directives: {
    SafeHtml: SafeHtmlDirective,
    GlTooltip: GlTooltipDirective
  },
  provide() {
    return {
      modalTitle: i18n.MODAL.TITLE,
      modalAlertText: i18n.MODAL.ALERT_TEXT
    };
  },
  inject: {
    // Note, we likely might move away from Provide/Inject for this
    // and only ship the versions that are currently in the default
    // See https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/3953#note_1762834219
    // for more context.
    renderGFM: {
      from: 'renderGFM',
      default: () => element => {
        element.classList.add('gl-markdown', 'gl-compact-markdown');
      }
    },
    renderMarkdown: {
      from: 'renderMarkdown',
      default: () => renderDuoChatMarkdownPreview
    }
  },
  props: {
    /**
     * A message object
     */
    message: {
      type: Object,
      required: true
    },
    isCancelled: {
      type: Boolean,
      required: true
    }
  },
  data() {
    return {
      didWhat: '',
      improveWhat: '',
      messageWatcher: null,
      // imperatively set up watcher on message
      messageChunks: [],
      selectedContextItemsDefaultCollapsed: SELECTED_CONTEXT_ITEMS_DEFAULT_COLLAPSED
    };
  },
  computed: {
    isChunk() {
      return typeof this.message.chunkId === 'number';
    },
    isNotChunkOrCancelled() {
      return !this.isChunk || this.isCancelled;
    },
    isChunkAndNotCancelled() {
      return this.isChunk && !this.isCancelled;
    },
    isAssistantMessage() {
      return this.message.role.toLowerCase() === MESSAGE_MODEL_ROLES.assistant;
    },
    isUserMessage() {
      return this.message.role.toLowerCase() === MESSAGE_MODEL_ROLES.user;
    },
    sources() {
      var _this$message$extras;
      return (_this$message$extras = this.message.extras) === null || _this$message$extras === void 0 ? void 0 : _this$message$extras.sources;
    },
    hasFeedback() {
      var _this$message$extras2;
      return (_this$message$extras2 = this.message.extras) === null || _this$message$extras2 === void 0 ? void 0 : _this$message$extras2.hasFeedback;
    },
    defaultContent() {
      if (this.message.contentHtml) {
        return this.message.contentHtml;
      }
      return this.renderMarkdown(this.message.content);
    },
    messageContent() {
      if (this.isAssistantMessage && this.isChunk) {
        return this.renderMarkdown(concatUntilEmpty(this.messageChunks));
      }
      return this.defaultContent || this.renderMarkdown(concatUntilEmpty(this.message.chunks));
    },
    renderedError() {
      var _this$message$errors;
      return this.renderMarkdown(((_this$message$errors = this.message.errors) === null || _this$message$errors === void 0 ? void 0 : _this$message$errors.join('; ')) || '');
    },
    error() {
      var _this$message, _this$message$errors2;
      return Boolean((_this$message = this.message) === null || _this$message === void 0 ? void 0 : (_this$message$errors2 = _this$message.errors) === null || _this$message$errors2 === void 0 ? void 0 : _this$message$errors2.length) && this.message.errors.join('; ');
    },
    selectedContextItems() {
      var _this$message$extras3;
      return ((_this$message$extras3 = this.message.extras) === null || _this$message$extras3 === void 0 ? void 0 : _this$message$extras3.contextItems) || [];
    },
    displaySelectedContextItems() {
      return Boolean(this.selectedContextItems.length);
    },
    selectedContextItemsTitle() {
      if (!this.displaySelectedContextItems) return '';
      const count = this.selectedContextItems.length;
      if (this.isUserMessage) {
        return translatePlural('GlDuoChatMessage.SelectedContextItemsTitleUserMessage', 'Included reference', 'Included references')(count);
      }
      return sprintf(translatePlural('GlDuoChatMessage.SelectedContextItemsTitleAssistantMessage', 'Used %{count} included reference', 'Used %{count} included references')(count), {
        count
      });
    }
  },
  beforeCreate() {
    if (!customElements.get('copy-code')) {
      customElements.define('copy-code', CopyCodeElement);
    }
    if (!customElements.get('insert-code-snippet')) {
      customElements.define('insert-code-snippet', InsertCodeSnippetElement);
    }
  },
  mounted() {
    if (this.isAssistantMessage) {
      // The watcher has to be created imperatively here
      // to give an opportunity to remove it after
      // the complete message has arrived
      this.messageWatcher = this.$watch('message', this.manageMessageUpdate);
    }
    this.setChunks();
    this.hydrateContentWithGFM();
  },
  updated() {
    this.hydrateContentWithGFM();
  },
  methods: {
    setChunks() {
      if (this.isChunk) {
        const {
          chunkId,
          content
        } = this.message;
        this.$set(this.messageChunks, chunkId - 1, content);
      } else {
        this.messageChunks = [];
      }
    },
    stopWatchingMessage() {
      if (this.messageWatcher) {
        this.messageWatcher(); // Stop watching the message prop
        this.messageWatcher = null; // Ensure the watcher can't be stopped multiple times
      }
    },
    hydrateContentWithGFM() {
      if (!this.isChunk && this.$refs.content) {
        this.$nextTick(this.renderGFM(this.$refs.content));
      }
    },
    logEvent(e) {
      this.$emit('track-feedback', {
        ...e,
        didWhat: this.didWhat,
        improveWhat: this.improveWhat,
        message: this.message
      });
    },
    manageMessageUpdate() {
      this.setChunks();
      if (!this.isChunk) {
        this.stopWatchingMessage();
      }
    },
    onInsertCodeSnippet(e) {
      this.$emit('insert-code-snippet', e);
    },
    onGetContextItemContent(contextItem) {
      this.$emit('get-context-item-content', {
        messageId: this.message.id,
        contextItem
      });
    }
  }
};

/* script */
const __vue_script__ = script;

/* template */
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"duo-chat-message gl-mb-4 gl-rounded-lg gl-p-4 gl-leading-20 gl-break-anywhere",class:{
    'gl-ml-auto gl-rounded-br-none gl-bg-blue-100 gl-text-blue-900': _vm.isUserMessage,
    'gl-rounded-bl-none gl-border-1 gl-border-solid gl-border-gray-50 gl-text-gray-900':
      _vm.isAssistantMessage,
    'gl-bg-white': _vm.isAssistantMessage && !_vm.error,
    '!gl-border-none gl-bg-red-50': _vm.error,
  },on:{"insert-code-snippet":_vm.onInsertCodeSnippet}},[(_vm.error)?_c('gl-icon',{staticClass:"error-icon gl-border gl-mr-3 gl-shrink-0 gl-rounded-full gl-border-red-500 gl-text-red-600",attrs:{"aria-label":_vm.$options.i18n.MESSAGE_ERROR,"name":"status_warning_borderless","size":16,"data-testid":"error"}}):_vm._e(),_vm._v(" "),_c('div',{ref:"content-wrapper",class:{ 'has-error': _vm.error }},[(_vm.displaySelectedContextItems && _vm.isAssistantMessage)?_c('gl-duo-chat-context-item-selections',{attrs:{"selections":_vm.selectedContextItems,"title":_vm.selectedContextItemsTitle,"default-collapsed":_vm.selectedContextItemsDefaultCollapsed,"variant":"assistant"},on:{"get-content":_vm.onGetContextItemContent}}):_vm._e(),_vm._v(" "),(_vm.error)?_c('div',{directives:[{name:"safe-html",rawName:"v-safe-html:[$options.safeHtmlConfigExtension]",value:(_vm.renderedError),expression:"renderedError",arg:_vm.$options.safeHtmlConfigExtension}],ref:"error-message"}):_c('div',[_c('div',{directives:[{name:"safe-html",rawName:"v-safe-html:[$options.safeHtmlConfigExtension]",value:(_vm.messageContent),expression:"messageContent",arg:_vm.$options.safeHtmlConfigExtension}],ref:"content"}),_vm._v(" "),(_vm.isAssistantMessage)?[(_vm.sources)?_c('documentation-sources',{attrs:{"sources":_vm.sources}}):_vm._e(),_vm._v(" "),_c('div',{staticClass:"duo-chat-message-feedback gl-mt-4 gl-flex gl-items-end"},[(_vm.isChunkAndNotCancelled)?_c('gl-loading-icon',{staticClass:"gl-pt-4",attrs:{"variant":"dots","inline":""}}):_vm._e(),_vm._v(" "),(_vm.isNotChunkOrCancelled)?_c('gl-duo-user-feedback',{attrs:{"feedback-received":_vm.hasFeedback,"modal-title":_vm.$options.i18n.MODAL.TITLE,"modal-alert":_vm.$options.i18n.MODAL.ALERT_TEXT},on:{"feedback":_vm.logEvent},scopedSlots:_vm._u([{key:"feedback-extra-fields",fn:function(){return [_c('gl-form-group',{attrs:{"label":_vm.$options.i18n.MODAL.DID_WHAT,"optional":""}},[_c('gl-form-textarea',{attrs:{"placeholder":_vm.$options.i18n.MODAL.INTERACTION},model:{value:(_vm.didWhat),callback:function ($$v) {_vm.didWhat=$$v;},expression:"didWhat"}})],1),_vm._v(" "),_c('gl-form-group',{attrs:{"label":_vm.$options.i18n.MODAL.IMPROVE_WHAT,"optional":""}},[_c('gl-form-textarea',{attrs:{"placeholder":_vm.$options.i18n.MODAL.BETTER_RESPONSE},model:{value:(_vm.improveWhat),callback:function ($$v) {_vm.improveWhat=$$v;},expression:"improveWhat"}})],1)]},proxy:true}],null,false,419229417)}):_vm._e()],1)]:_vm._e()],2),_vm._v(" "),(_vm.displaySelectedContextItems && _vm.isUserMessage)?_c('gl-duo-chat-context-item-selections',{attrs:{"selections":_vm.selectedContextItems,"title":_vm.selectedContextItemsTitle,"default-collapsed":_vm.selectedContextItemsDefaultCollapsed,"variant":"user"},on:{"get-content":_vm.onGetContextItemContent}}):_vm._e()],1)],1)};
var __vue_staticRenderFns__ = [];

  /* style */
  const __vue_inject_styles__ = undefined;
  /* scoped */
  const __vue_scope_id__ = undefined;
  /* module identifier */
  const __vue_module_identifier__ = undefined;
  /* functional template */
  const __vue_is_functional_template__ = false;
  /* style inject */
  
  /* style inject SSR */
  
  /* style inject shadow dom */
  

  
  const __vue_component__ = __vue_normalize__(
    { render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ },
    __vue_inject_styles__,
    __vue_script__,
    __vue_scope_id__,
    __vue_is_functional_template__,
    __vue_module_identifier__,
    false,
    undefined,
    undefined,
    undefined
  );

export default __vue_component__;
export { i18n };
