<script>
import { useAlert } from 'dashboard/composables';
import { mapGetters } from 'vuex';
import { useMessageFormatter } from 'shared/composables/useMessageFormatter';
import ContextMenu from 'dashboard/components/ui/ContextMenu.vue';
import AddCannedModal from 'dashboard/routes/dashboard/settings/canned/AddCanned.vue';
import CreateResponseDialog from 'dashboard/components-next/captain/pageComponents/response/CreateResponseDialog.vue';
import { useSnakeCase } from 'dashboard/composables/useTransformKeys';
import { copyTextToClipboard } from 'shared/helpers/clipboard';
import { conversationUrl, frontendURL } from '../../../helper/URLHelper';
import {
  ACCOUNT_EVENTS,
  CONVERSATION_EVENTS,
} from '../../../helper/AnalyticsHelper/events';
import MenuItem from '../../../components/widgets/conversation/contextMenu/menuItem.vue';
import { useTrack } from 'dashboard/composables';
import NextButton from 'dashboard/components-next/button/Button.vue';
import Editor from 'dashboard/components-next/Editor/Editor.vue';
import { useUISettings } from 'dashboard/composables/useUISettings';

export default {
  components: {
    AddCannedModal,
    CreateResponseDialog,
    MenuItem,
    ContextMenu,
    NextButton,
    Editor,
  },
  props: {
    message: {
      type: Object,
      required: true,
    },
    isOpen: {
      type: Boolean,
      default: false,
    },
    enabledOptions: {
      type: Object,
      default: () => ({}),
    },
    contextMenuPosition: {
      type: Object,
      default: () => ({}),
    },
    hideButton: {
      type: Boolean,
      default: false,
    },
  },
  emits: ['open', 'close', 'replyTo'],
  setup() {
    const { getPlainText } = useMessageFormatter();
    const { isEditorHotKeyEnabled } = useUISettings();

    return {
      getPlainText,
      isEditorHotKeyEnabled,
    };
  },
  data() {
    return {
      isCannedResponseModalOpen: false,
      isFaqModalOpen: false,
      showDeleteModal: false,
      showEditModal: false,
      editedContent: '',
      isEditingMessage: false,
    };
  },
  computed: {
    ...mapGetters({
      getAccount: 'accounts/getAccount',
      currentAccountId: 'getCurrentAccountId',
      getUISettings: 'getUISettings',
      copilotAssistant: 'getCopilotAssistant',
    }),
    plainTextContent() {
      return this.getPlainText(this.messageContent);
    },
    conversationId() {
      return this.message.conversation_id ?? this.message.conversationId;
    },
    messageId() {
      return this.message.id;
    },
    messageContent() {
      return this.message.content;
    },
    contentAttributes() {
      return useSnakeCase(
        this.message.content_attributes ?? this.message.contentAttributes
      );
    },
  },
  methods: {
    handleEnterKey(e) {
      if (this.isEditorHotKeyEnabled('enter')) {
        e.preventDefault();
        this.confirmEdit();
      }
    },
    handleCmdEnterKey() {
      if (this.isEditorHotKeyEnabled('cmd_enter')) {
        this.confirmEdit();
      }
    },
    async copyLinkToMessage() {
      const fullConversationURL =
        window.chatwootConfig.hostURL +
        frontendURL(
          conversationUrl({
            id: this.conversationId,
            accountId: this.currentAccountId,
          })
        );
      await copyTextToClipboard(
        `${fullConversationURL}?messageId=${this.messageId}`
      );
      useAlert(this.$t('CONVERSATION.CONTEXT_MENU.LINK_COPIED'));
      this.handleClose();
    },
    async handleCopy() {
      await copyTextToClipboard(this.plainTextContent);
      useAlert(this.$t('CONTACT_PANEL.COPY_SUCCESSFUL'));
      this.handleClose();
    },
    showCannedResponseModal() {
      useTrack(ACCOUNT_EVENTS.ADDED_TO_CANNED_RESPONSE);
      this.isCannedResponseModalOpen = true;
      this.handleClose();
    },
    hideCannedResponseModal() {
      this.isCannedResponseModalOpen = false;
    },
    async showFaqModal() {
      useTrack(ACCOUNT_EVENTS.ADDED_TO_CANNED_RESPONSE);
      try {
        await this.$store.dispatch(
          'getInboxCaptainAssistantById',
          this.conversationId
        );
      } catch (error) {
        // Silence error, we can still open the modal
      }
      this.isFaqModalOpen = true;
      this.handleClose();
      this.$nextTick(() => {
        this.$refs.faqDialog?.dialogRef?.open();
      });
    },
    hideFaqModal() {
      this.isFaqModalOpen = false;
    },
    handleOpen(e) {
      this.$emit('open', e);
    },
    handleClose(e) {
      this.$emit('close', e);
    },
    handleTranslate() {
      const { locale: accountLocale } = this.getAccount(this.currentAccountId);
      const agentLocale = this.getUISettings?.locale;
      const targetLanguage = agentLocale || accountLocale || 'en';
      this.$store.dispatch('translateMessage', {
        conversationId: this.conversationId,
        messageId: this.messageId,
        targetLanguage,
      });
      useTrack(CONVERSATION_EVENTS.TRANSLATE_A_MESSAGE);
      this.handleClose();
    },
    handleReplyTo() {
      this.$emit('replyTo', this.message);
      this.handleClose();
    },
    openDeleteModal() {
      this.handleClose();
      this.showDeleteModal = true;
    },
    async confirmDeletion() {
      try {
        await this.$store.dispatch('deleteMessage', {
          conversationId: this.conversationId,
          messageId: this.messageId,
        });
        useAlert(this.$t('CONVERSATION.SUCCESS_DELETE_MESSAGE'));
        this.showDeleteModal = false;
      } catch (error) {
        useAlert(this.$t('CONVERSATION.FAIL_DELETE_MESSSAGE'));
      }
    },
    closeDeleteModal() {
      this.showDeleteModal = false;
    },
    openEditModal() {
      this.handleClose();
      this.editedContent = this.messageContent;
      this.showEditModal = true;
    },
    closeEditModal() {
      this.showEditModal = false;
      this.editedContent = '';
    },
    async confirmEdit() {
      const trimmedContent = this.editedContent.trim();
      if (!trimmedContent) {
        useAlert(this.$t('CONVERSATION.CONTEXT_MENU.EDIT.EMPTY_CONTENT'));
        return;
      }
      if (trimmedContent === (this.messageContent || '').trim()) {
        this.closeEditModal();
        return;
      }
      this.isEditingMessage = true;
      try {
        await this.$store.dispatch('editMessage', {
          conversationId: this.conversationId,
          messageId: this.messageId,
          content: trimmedContent,
        });
        useAlert(this.$t('CONVERSATION.CONTEXT_MENU.EDIT.SUCCESS'));
        this.closeEditModal();
      } catch (error) {
        useAlert(this.$t('CONVERSATION.CONTEXT_MENU.EDIT.ERROR'));
      } finally {
        this.isEditingMessage = false;
      }
    },
  },
};
</script>

<template>
  <div class="context-menu">
    <!-- Add To Canned Responses -->
    <woot-modal
      v-if="isCannedResponseModalOpen"
      v-model:show="isCannedResponseModalOpen"
      :on-close="hideCannedResponseModal"
    >
      <AddCannedModal
        :response-content="plainTextContent"
        :on-close="hideCannedResponseModal"
      />
    </woot-modal>
    <!-- Add To FAQ -->
    <CreateResponseDialog
      v-if="isFaqModalOpen"
      ref="faqDialog"
      type="create"
      :selected-response="{
        question: plainTextContent,
        assistant_id: copilotAssistant?.id,
      }"
      @close="hideFaqModal"
    />
    <!-- Confirm Deletion -->
    <woot-delete-modal
      v-if="showDeleteModal"
      v-model:show="showDeleteModal"
      class="context-menu--delete-modal"
      :on-close="closeDeleteModal"
      :on-confirm="confirmDeletion"
      :title="$t('CONVERSATION.CONTEXT_MENU.DELETE_CONFIRMATION.TITLE')"
      :message="$t('CONVERSATION.CONTEXT_MENU.DELETE_CONFIRMATION.MESSAGE')"
      :confirm-text="$t('CONVERSATION.CONTEXT_MENU.DELETE_CONFIRMATION.DELETE')"
      :reject-text="$t('CONVERSATION.CONTEXT_MENU.DELETE_CONFIRMATION.CANCEL')"
    />
    <!-- Edit Message Modal -->
    <woot-modal
      v-if="showEditModal"
      v-model:show="showEditModal"
      :on-close="closeEditModal"
    >
      <div class="flex flex-col h-auto overflow-auto">
        <woot-modal-header
          :header-title="$t('CONVERSATION.CONTEXT_MENU.EDIT.TITLE')"
        />
        <form
          class="flex flex-col w-full"
          @submit.prevent="confirmEdit"
          @keydown.enter.exact="handleEnterKey"
          @keydown.meta.enter="handleCmdEnterKey"
          @keydown.ctrl.enter="handleCmdEnterKey"
        >
          <Editor
            v-model="editedContent"
            :label="$t('CONVERSATION.CONTEXT_MENU.EDIT.PLACEHOLDER')"
            :placeholder="$t('CONVERSATION.CONTEXT_MENU.EDIT.PLACEHOLDER')"
            :max-length="4096"
            :show-character-count="false"
            :enable-canned-responses="false"
            focus-on-mount
          />
          <div class="flex flex-row justify-end w-full gap-2 px-0 py-2">
            <NextButton
              faded
              slate
              type="reset"
              :label="$t('CONVERSATION.CONTEXT_MENU.EDIT.CANCEL')"
              @click.prevent="closeEditModal"
            />
            <NextButton
              type="submit"
              :label="$t('CONVERSATION.CONTEXT_MENU.EDIT.SAVE')"
              :disabled="!editedContent.trim()"
              :is-loading="isEditingMessage"
              icon="i-lucide-corner-down-left"
              trailing-icon
            />
          </div>
        </form>
      </div>
    </woot-modal>

    <NextButton
      v-if="!hideButton"
      ghost
      slate
      sm
      icon="i-lucide-ellipsis-vertical"
      class="invisible group-hover/context-menu:visible"
      @click="handleOpen"
    />

    <ContextMenu
      v-if="isOpen"
      :x="contextMenuPosition.x"
      :y="contextMenuPosition.y"
      @close="handleClose"
    >
      <div class="menu-container">
        <MenuItem
          v-if="enabledOptions['replyTo']"
          :option="{
            icon: 'arrow-reply',
            label: $t('CONVERSATION.CONTEXT_MENU.REPLY_TO'),
          }"
          variant="icon"
          @click.stop="handleReplyTo"
        />
        <MenuItem
          v-if="enabledOptions['copy']"
          :option="{
            icon: 'clipboard',
            label: $t('CONVERSATION.CONTEXT_MENU.COPY'),
          }"
          variant="icon"
          @click.stop="handleCopy"
        />
        <MenuItem
          v-if="enabledOptions['translate']"
          :option="{
            icon: 'translate',
            label: $t('CONVERSATION.CONTEXT_MENU.TRANSLATE'),
          }"
          variant="icon"
          @click.stop="handleTranslate"
        />
        <hr />
        <MenuItem
          v-if="enabledOptions['copyLink']"
          :option="{
            icon: 'link',
            label: $t('CONVERSATION.CONTEXT_MENU.COPY_PERMALINK'),
          }"
          variant="icon"
          @click.stop="copyLinkToMessage"
        />
        <MenuItem
          v-if="enabledOptions['cannedResponse']"
          :option="{
            icon: 'comment-add',
            label: 'Criar FAQ',
          }"
          variant="icon"
          @click.stop="showFaqModal"
        />
        <MenuItem
          v-if="enabledOptions['edit']"
          :option="{
            icon: 'edit',
            label: $t('CONVERSATION.CONTEXT_MENU.EDIT.LABEL'),
          }"
          variant="icon"
          @click.stop="openEditModal"
        />
        <hr v-if="enabledOptions['delete']" />
        <MenuItem
          v-if="enabledOptions['delete']"
          :option="{
            icon: 'delete',
            label: $t('CONVERSATION.CONTEXT_MENU.DELETE'),
          }"
          variant="icon"
          @click.stop="openDeleteModal"
        />
      </div>
    </ContextMenu>
  </div>
</template>

<style lang="scss" scoped>
.menu-container {
  @apply p-1 bg-n-background shadow-xl rounded-md;

  hr:first-child {
    @apply hidden;
  }

  hr {
    @apply m-1 border-b border-solid border-n-strong;
  }
}

.context-menu--delete-modal {
  ::v-deep {
    .modal-container {
      @apply max-w-[30rem];

      h2 {
        @apply font-medium text-base;
      }
    }
  }
}
</style>
