<template>
  <BsLayoutDefault ref="layout">
    <BsHeader>
      <BsButton
        v-if="!layout?.drawerOpen"
        flat
        round
        class="open-side-drawer-btn"
        size="15px"
        @click="closeSideDrawer"
        icon="mdi-arrow-right"
      >
      <BsTooltip>Open side bar</BsTooltip>
    </BsButton>
    <div style="height:54px; width:20px; clear:both;"></div>
    </BsHeader>
    <BsDrawer>
    <BsButton
          flat
          round
          class="close-side-drawer-btn"
          size="15px"
          @click="closeSideDrawer"
          icon="mdi-arrow-left"
      >
          <BsTooltip>Close side bar</BsTooltip>
      </BsButton>
      <q-scroll-area class="fit">
        <div class="q-ma-md q-mt-lg row q-gutter-y-md">
          <span class="drawer-title">Automatic Reporting</span>
          <FFSelect
            :modelValue="selectedBU"
            :options="businessUnits"
            @update:modelValue="updateBU"
            label="Select a business unit"
            helpMessage="A custom email will be generated on selection"
            style="min-width: 250px"
          >
          </FFSelect>
          <InfoBadge
            :text="currentInfoState.text"
            :icon="currentInfoState.icon"
            :color="currentInfoState.color"
          />
        </div>
      </q-scroll-area>
    </BsDrawer>
    <BsDocumentation
     :doc-icon="docIcon"
     doc-title="Financial Forecasting">
          <DocumentationContent></DocumentationContent>
      </BsDocumentation>
    <BsContent>
      <EmptyState
                    title="Financial Forecasting Report Generator"
                    subtitle="Select a business unit from the left panel.<br>
                              You will get a sourced report with the results from your dashboard.<br>
                              You can then modify it with written instructions according to your content or formatting needs."
                    v-if="!selectedBU"
                />
      <div class="main-container column no-wrap q-gutter-y-md" v-if="selectedBU">
        <BsWarning
        v-if="saved"
        :text="savedReportMessage"
        :closable=true
        warning-type="success"
        />
        <form
          autocorrect="off"
          autocapitalize="off"
          autocomplete="off"
          spellcheck="false"
        >
        <div class="editor-wrapper">
          <q-editor
            ref="editorRef"
            v-model="editor"
            :toolbar="dynamicToolbar"
            :disable="disableEdit"
            @keydown="removeSave"
            maxHeight="400px"
            height="400px"
            maxWidth="800px"
            width="800px"
          />
          <q-separator class="toolbar-separator" />
        </div>
        </form>
        <InstructionMenu 
          @undo="undoReport"
          @refine="refineReport"
          @copy="copyReport"
          @save="saveReport"
          :refineActive="activateToolbar"
          :disableUndo="disableUndo" />
        <BsWarning
        text="If you wish to modify the report with written instructions, use the fields below"
        :closable=true
        />
        <q-input
              v-model="instruction"
              outlined
              dense
              style="width: 100%"
              placeholder="Type your instruction here..."
              @keydown.enter="handleEnterKey"
            >
              <template v-slot:append>
                <q-icon
                  name="send"
                  class="cursor-pointer send-icon"
                  @click="sendInstruction"
                  size="xs"
                  :style="activeStyle"
                />
              </template>
            </q-input>
      </div>
      <Disclaimer />
    </BsContent>
  </BsLayoutDefault>
</template>

<script lang="ts">
import docIcon from "./assets/images/doc-logo-example.svg";

import { API } from "./Api";
import { onMounted, ref, computed } from "vue";
import { Loading, Notify } from "quasar";
import { BusinessUnit, QuestionData, SESSION_STORAGE_HISTORY_KEY } from './models'
import FFSelect from "./components/FFSelect.vue";
import EmptyState from "./components/EmptyState.vue";
import { defineComponent } from "vue";
import DocumentationContent from "./components/DocumentationContent.vue";
import InstructionMenu from "./components/InstructionMenu.vue"
import BsWarning from "./components/BsWarning.vue"
import { useQuasar } from 'quasar'
import { BsLayoutDefault } from "quasar-ui-bs";

const $q = useQuasar()

const initData: QuestionData = {
  query: '',
  email: ''
}

export default defineComponent({
  data() {
    return {
      history: [] as QuestionData[],
      queriesAnswers: [] as QuestionData[],
      docIcon,
      currentData: { ...initData },
      loading: false,
      editorToolbar: ['left', 'right'],
      disableEdit: true,
      saved: false,
      savedFolderUrl: "",
      infoStates: {
        selectBU: {
          text: "Please select a business unit",
          icon: "radio_button_checked",
          color: "primary",
        },
        waitingForSelection: {
          text: "Waiting for business unit selection",
          icon: "hourglass_empty",
          color: "primary",
        },
        GeneratingEmail: {
          text: "Generating email ...",
          icon: "history_edu",
          color: "primary",
        },
        GeneratingInstruction: {
          text: "Generating with instructions ...",
          icon: "history_edu",
          color: "primary",
        },
        SendingEmail: {
          text: "Sending email...",
          icon: "outgoing_mail",
          color: "primary",
        },
        EmailSent: {
          text: "Email sent!",
          icon: "check_circle",
          color: "positive",
        },
        Error: {
          text: "An error occurred. Please try again.",
          icon: "error",
          color: "negative",
        },
      },
      currentInfoState : {
          text: "Please select a business unit",
          icon: "radio_button_checked",
          color: "primary",
        },
      businessUnits : [],
      instruction : "" as string,
      selectedBU: "" as string,
      activateToolbar: false,
      editorRef: null,
      disableUndo: true,
      editor: "Welcome! Please select a business unit to generate a financial forecasting report.",
      layout: undefined as undefined | typeof BsLayoutDefault
    }
  },
  computed: {
    historySessionId(){
      return `${this.getWebAppId()}-${SESSION_STORAGE_HISTORY_KEY}`;
    },
    activeStyle() {
      if (this.loading) {
        return {
          color: '#CCCCCC',
          cursor: 'wait !important'
        }
      } else {
        if (this.instruction) {
          return {
            color: '#01B2AA',
            cursor: 'pointer'
          }
        } else {
          return {
            color: '#CCCCCC',
            cursor: 'not-allowed !important'
          }
        }
      }
    },
    dynamicToolbar() {
        if (this.activateToolbar) {
          return [
            ['left', 'right', 'center', 'justify'],
            ['bold', 'italic', 'strike', 'underline', 'subscript', 'superscript'],
          ];
        } else {
          return [];
      }
    },
    savedReportMessage() {
      return "Your report is saved, you can find it in <a href='" + this.savedFolderUrl + "' target='_blank'>saved_reports</a>"
    }
  },
  components: {
    FFSelect,
    EmptyState,
    DocumentationContent,
    InstructionMenu,
    BsWarning
  },
  watch: {
    loading(newVal) {
      if (newVal) {
        Loading.show({
            message: "Loading report ...",
            boxClass: "text-grey-9",
            spinnerColor: "primary",
        });
      } else {
          Loading.hide();
      }
    }
  },
  methods: {
    async updateBU(value: string) {
      this.loading = true;
      this.saved = false;
      this.clearHistory();
      this.selectedBU = value;
      this.currentInfoState = this.infoStates.GeneratingEmail;
      try {
        const emailResponse = await API.generateEmail({ business_unit: value });
        this.currentInfoState = this.infoStates.waitingForSelection;
        this.editor = emailResponse?.data.email;
        this.currentData = {
            ...this.currentData,
            query: "Generate the financial forecasting report",
            email: this.editor,
          }
        this.addToHistory();
        this.loading = false;
        this.activateToolbar = false;
      } catch (e) {
        this.currentInfoState = this.infoStates.Error;
      }
    },
    async sendInstruction() {
      if (this.instruction && this.instruction !== "") {
        try {
          this.loading = true;
          this.currentInfoState = this.infoStates.GeneratingInstruction;
          const emailResponse = await API.sendInstruction({
            query: this.instruction,
            history: this.retrieveHistory(),
          });
          if (emailResponse && emailResponse?.data) {
            this.editor = emailResponse?.data.email;
            this.currentData = {
              ...this.currentData,
              query: this.instruction,
              email: emailResponse?.data.email,
            }
            this.loading = false;
            this.addToHistory();
            this.disableUndo = false;
            this.saved = false;
            if (emailResponse?.data.success_error == 0) {
              this.notifyUser({message: "Error in the generated report!", type: "error"});
            }
          }
          this.currentInfoState = this.infoStates.waitingForSelection;
        } catch (e) {
          this.currentInfoState = this.infoStates.Error;
        }
      }
    },
    async saveReport() {
      if (
        this.editor &&
        this.editor !=
          "Welcome! Please select a customer to generate a specialized email."
      ) {
        try {
          this.currentInfoState = this.infoStates.SendingEmail;
          const isReportSaved = await API.saveReport({
            email: this.editor,
            business_unit: this.selectedBU
          });
          if (isReportSaved && isReportSaved.data) {
            this.currentInfoState = this.infoStates.EmailSent;
            this.saved = true;
          } else {
            this.currentInfoState = this.infoStates.Error;
            this.notifyUser({message: "Error while saving the report!", type: "error"});
          }
        } catch (e) {
          console.error(e);
          this.currentInfoState = this.infoStates.Error;
          this.notifyUser({message: "Error while saving the report!", type: "error"});
        }
      }
    },
    async copyReport() {
      try {
        if (this.editor && this.editor.trim() !== '') {
          await navigator.clipboard.writeText(this.editor.trim());
          this.notifyUser({message: 'Content copied to clipboard!', type: 'success'});
        } else {
          this.notifyUser({message: 'Editor is empty!', type: "error"});
        }
      } catch (error) {
        this.notifyUser({message: 'Failed to copy content to clipboard!', type: "error"});
      }
    },
    refineReport(refineActive: boolean) {
      this.saved = false;
      this.activateToolbar = refineActive;
      this.disableEdit = !this.activateToolbar;
    },
    undoReport() {
      const history = this.retrieveHistory();
      history.pop();
      const lastElement = history[history.length - 1];
      this.editor = lastElement.email;
      if (history.length < 2) {
        this.disableUndo = true;
      }
    },
    notifyUser(info: any) {
      // { type: "success", message: msg }
      // Notify.create({
      //     type: "positive",
      //     message: message,
      //     position: "top",
      //     color: "positive-alert",
      //     textColor: "positive-alert",
      //     icon: "check",
      //     classes: "bs-font-medium-1-semi-bold bs-alert-notification",
      //     actions: [
      //         {
      //             icon: "close",
      //             color: "positive-alert",
      //             round: true,
      //         },
      //     ],
      // });
      if (info.type === "success") {
                Notify.create({
                    type: "positive",
                    message: info.message,
                    position: "top",
                    color: "positive-alert",
                    textColor: "positive-alert",
                    icon: "check",
                    classes: "bs-font-medium-1-semi-bold bs-alert-notification",
                    actions: [
                        {
                            icon: "close",
                            color: "positive-alert",
                            round: true,
                        },
                    ],
                });
            } else {
                Notify.create({
                    type: "negative",
                    message: info.message,
                    position: "top",
                    color: "negative-alert",
                    textColor: "negative-alert",
                    icon: "mdi-close-circle-outline",
                    classes: "bs-font-medium-1-semi-bold bs-alert-notification",
                    actions: [
                        {
                            icon: "close",
                            color: "negative-alert",
                            round: true,
                        },
                    ],
                });
            }
        },
    handleEnterKey: function (event: any) {
      event.stopPropagation()
      event.preventDefault()
      this.sendInstruction()
    },
    removeSave: function(event: any) {
      this.saved = false;
    },
    clearHistory() {
      sessionStorage.clear()
      this.queriesAnswers = []
      this.currentData = { ...initData }
    },
    getWebAppId(){
      const urlObj = new URL(window.location.href);
      const params = new URLSearchParams(urlObj.search);
      const value = params.get('webAppId');
      return value;
    },
    retrieveHistory(): QuestionData[] {
      let history = [] as QuestionData[]
      if (sessionStorage.getItem(this.historySessionId)) {
        history = JSON.parse(sessionStorage.getItem(this.historySessionId)!)
      }
      return history
    },
    addToHistory(){
      try{
        this.queriesAnswers.push(this.currentData)
        sessionStorage.setItem(this.historySessionId, JSON.stringify(this.queriesAnswers))
      }catch(err: any){
        if (err.name === 'QuotaExceededError') {
          console.error("Exceeded quota, history cleared")
          // Exceeded quota, need to clear the cache
          this.clearHistory();
        }
      }
    },
    closeSideDrawer() {
      if (this.layout) {
        this.layout.drawerOpen = !this.layout.drawerOpen
      }
    }
  },
  mounted() {
    API.getBusinessUnits()
            .then((data: any) => {
              this.businessUnits = data.data.map(
                (x: BusinessUnit) => x.business_unit
              );
            });
    API.getSavedFolderUrl()
            .then((data: any) => {
              this.savedFolderUrl = data.data;
            });
      this.layout = this.$refs.layout as InstanceType<typeof BsLayoutDefault>;
    }
})
</script>
<style scope>
.main-container {
    padding: 16px;
    padding-top: 48px;
    width: 800px
}

.q-field {
  margin-top: 0;
}

.editor-wrapper {
  position: relative;
}

.q-editor .q-editor__toolbars-container {
  position: absolute;
  bottom: 0;
  width: 100%;
  z-index: 1; /* Ensure the toolbar is above the editor content */
}

.q-editor__content {
  margin-bottom: 30px; /* Adjust the margin between editor content and toolbar */
}

.q-separator {
  margin-top: 30px 0; /* Adjust the margin around the separator */
}

.close-side-drawer-btn {
    color: var(--interactions-bs-color-interaction-primary, #2b66ff);
    position: absolute;
    top: 7px;
    right: 10px;
    z-index: 1000;
}
.open-side-drawer-btn {
    color: var(--interactions-bs-color-interaction-primary, #2b66ff);
    position: relative;
    top: -14px;
    left: 10px;
}

.drawer-title {
  margin-top: 0;
  color: var(--interactions-bs-color-interaction-primary, #2B66FF);
  /* bs-font-medium-4-semi-bold */
  font-family: SourceSansPro;
  font-size: 20px;
  font-style: normal;
  font-weight: 600;
  line-height: 32px; /* 160% */
}

.q-mt-lg {
    margin-top: 12px;
}

.q-field__native {
  padding: 0;
}

.toggle-left-button {
    display: none;
}

.text-positive-alert {
    color: #0b590b !important;
}
.bg-positive-alert {
    background-color: #d7f0d6 !important;
}
.text-negative-alert {
    color: #ce1228 !important;
}
.bg-negative-alert {
    background-color: #f9e3e5 !important;
}
.bg-interactions-bs-color-interaction-selected {
    background: var(--interactions-bs-color-interaction-selected, #214ab5);
}
.text-interactions-bs-color-interaction-selected {
    color: var(--interactions-bs-color-interaction-selected, #214ab5);
}
/* TODO move this to lib */
.bs-font-medium-1-semi-bold {
    /* bs-font-medium-1-semi-bold */
    font-size: 12px;
    font-style: normal;
    font-weight: 600;
    line-height: 20px; /* 166.667% */
}

.bs-alert-notification {
    min-width: 400px;
    border-radius: var(--bs-radius-messages, 0px);
    box-shadow: none;
    margin-top: 0;
}

.q-editor.disabled {
  border-style: solid;
}

.send-icon {
  margin-bottom: 4px;
  transform: rotate(-38.48deg);
}
</style>