<template>
  <v-container class="ma-0 pa-0"
               style="height:calc(100% - 50px)"
               fluid
               :style="cssStyle ? cssStyle : ''">

    <monaco-editor
      style="height: 100% "
      class="editor card"
      ref="editor"
      @selection="selectionFn"
      theme="vs-dark"
      v-model="codeLocal"
      language="sql"
      :minimap="minimap"
      :readOnly="readOnly"
      :actions="actions"
      :tables="tables"
      :columnNames="columnNames"
      :columnNameCbk="columnNameCbk"
    >
    </monaco-editor>


  </v-container>
</template>

<script>
  import MonacoEditor from "./index.js";
  import sqlFormatter from "sql-formatter";

  const monaco = require("monaco-editor");
  export default {
    ssr: false,
    components: {
      MonacoEditor,
      // sqlFormatter
    },
    beforeCreate() {
      // console.log(MonacoEditor)
    },
    data() {
      const vm = this;
      return {
        codeLocal: `${this.code || ""}`,
        selection: null,
        minimap: {
          enabled: true
        },
        actions: [{
          // An unique identifier of the contributed action.
          id: 'x-sql-pretify',
          // A label of the action that will be presented to the user.
          label: 'Format SQL',
          // An optional array of keybindings for the action.
          keybindings: [
            monaco.KeyMod.CtrlCmd | monaco.KeyMod.Alt | monaco.KeyCode.KEY_L
          ],
          // A precondition for this action.
          precondition: null,
          // A rule to evaluate on top of the precondition in order to dispatch the keybindings.
          keybindingContext: null,
          contextMenuGroupId: 'navigation',
          contextMenuOrder: 1.5,
          // Method that will be executed when the action is triggered.
          // @param editor The editor instance is passed in as a convinience
          run: function (ed) {
            vm.pretify()
          }
        }, {
          // An unique identifier of the contributed action.
          id: 'x-sql-execute',
          // A label of the action that will be presented to the user.
          label: 'Run Query',
          // An optional array of keybindings for the action.
          keybindings: [
            monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter
          ],
          // A precondition for this action.
          precondition: null,
          // A rule to evaluate on top of the precondition in order to dispatch the keybindings.
          keybindingContext: null,
          contextMenuGroupId: 'navigation',
          contextMenuOrder: 1.5,
          // Method that will be executed when the action is triggered.
          // @param editor The editor instance is passed in as a convinience
          run: function (ed) {
            vm.$emit('execute', ed)
          }
        }, {
          id: 'x-sql-run-all',
          label: 'Run All',
          keybindings: [
            monaco.KeyMod.CtrlCmd | monaco.KeyMod.Alt | monaco.KeyCode.Enter
          ],
          precondition: null,
          keybindingContext: null,
          contextMenuGroupId: 'navigation',
          contextMenuOrder: 1.5,
          run: function (ed) {
            vm.$emit('runAll', ed)
          }
        }, {
          id: 'x-sql-bookmark',
          label: 'Bookmark Query',
          keybindings: [
            monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_B
          ],
          precondition: null,
          keybindingContext: null,
          contextMenuGroupId: 'navigation',
          contextMenuOrder: 1.5,
          run: function (ed) {
            vm.$emit('bookmark', ed)
          }
        }, {
          id: 'x-sql-search',
          label: 'Search Query History',
          keybindings: [
            monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_P
          ],
          precondition: null,
          keybindingContext: null,
          contextMenuGroupId: 'navigation',
          contextMenuOrder: 1.5,
          run: function (ed) {
            vm.$emit('searchHistory', ed)
          }
        }, {
          id: 'x-sql-toggle-bookmark',
          label: 'Show/Hide Bookmarks',
          keybindings: [
            monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_K
          ],
          precondition: null,
          keybindingContext: null,
          contextMenuGroupId: 'navigation',
          contextMenuOrder: 1.5,
          run: function (ed) {
            vm.$emit('toggleBookmark', ed)
          }
        }, {
          id: 'x-sql-file-open',
          label: 'Open File',
          keybindings: [
            monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_O
          ],
          precondition: null,
          keybindingContext: null,
          contextMenuGroupId: 'navigation',
          contextMenuOrder: 1.5,
          run: function (ed) {
            vm.$emit('openFile', ed)
          }
        }, {
          id: 'x-sql-save-file',
          label: 'Save File',
          keybindings: [
            monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_S
          ],
          precondition: null,
          keybindingContext: null,
          contextMenuGroupId: 'navigation',
          contextMenuOrder: 1.5,
          run: function (ed) {
            vm.$emit('saveFile', ed)
          }
        }, {
          id: 'x-sql-clear-editor',
          label: 'Clear Editor',
          keybindings: [
            monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_N
          ],
          precondition: null,
          keybindingContext: null,
          contextMenuGroupId: 'navigation',
          contextMenuOrder: 1.5,
          run: function (ed) {
            vm.$emit('clearEditor', ed)
          }
        }]

      };
    },
    computed: {},
    props: ["code", "cssStyle", "readOnly", "heading", "tables", "columnNames", "columnNameCbk"],
    methods: {
      selectionFn() {
        const editor = this.$refs.editor.getMonaco();
        const range = editor.getSelection();
        const selectedText = editor.getModel().getValueInRange(range);
        // console.log('getValue', editor.getModel())
        this.selection = selectedText;
        this.selectionRange = range;
      },
      pretify() {
        // console.log("this.code", this.code);
        const editor = this.$refs.editor.getMonaco();

        if (this.selection && this.selectionRange) {
          const op = {
            identifier: "prettifySelection",
            range: this.selectionRange,
            text: sqlFormatter.format(this.selection),
            forceMoveMarkers: true
          };
          editor.executeEdits("sqlFormatter", [op]);
          this.selection = null;
          this.selectionRange = null;
        } else {
          // console.log("selected format before:: ", this.codeLocal);
          const op = {
            identifier: "prettifyDoc",
            range: editor.getModel().getFullModelRange(),
            text: sqlFormatter.format(this.codeLocal || ""),
            forceMoveMarkers: true
          };
          editor.executeEdits("sqlFormatter", [op]);
        }
      },
      toggleMiniMap() {
        const editor = this.$refs.editor.getMonaco();
        this.minimap.enabled = !this.minimap.enabled;
        editor.updateOptions({
          minimap: {
            enabled: this.minimap.enabled
          }
        });
      },
      getCurrentQuery() {
        return this.$refs.editor.getCurrentQuery();
      },
      getAllContent() {
        return this.$refs.editor.getAllContent();
      },
      focus() {
        this.$refs.editor.focus();
      }
    },
    watch: {
      codeLocal: function (newValue) {
        //INFO: for updating value of prop `code` in parent comp
        // console.log("update:code Event Emitted", newValue);
        this.$emit("update:code", newValue);
      },
      code: function (newValue) {
        this.codeLocal = newValue;
      }
    },
    created() {
      //
    }
  };
</script>

<style>
  .editor {
    /* width: 100%;
    height: 800px; */
  }
</style>
<!--
/**
 * @copyright Copyright (c) 2021, Xgene Cloud Ltd
 *
 * @author Naveen MR <oof1lab@gmail.com>
 * @author Pranav C Balan <pranavxc@gmail.com>
 *
 * @license GNU AGPL version 3 or any later version
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 */
-->