<template>
  <v-container fluid>
    <v-col
      :class="{ 'col-md-8 offset-md-2 col-sm-10 offset-sm-1 col-12': !edit }"
      style="position: relative"
    >
      <v-form ref="form" v-model="valid" :class="{ 'mt-8 pt-8': !edit }">
        <v-card ref="mainCard" class="elevation-5">
          <div
            v-if="!edit"
            style="
              position: absolute;
              top: -30px;
              left: -moz-calc(50% - 30px);
              left: -webkit-calc(50% - 30px);
              left: calc(50% - 30px);
              z-index: 999;
              border-radius: 10px;
            "
            class="primary"
          >
            <v-img
              class="mx-auto"
              width="60"
              height="60"
              :src="require('@/assets/img/icons/512x512-trans.png')"
              @dblclick="enableAllSchemas()"
            />
          </div>
          <v-toolbar
            flat
            color=""
            class="mb-3"
            style="
              width: 100%;
              border-bottom: 1px solid var(--v-backgroundColor-base);
            "
          >
            <v-toolbar-title class="title">
              <!-- Edit Project -->
              <span v-if="edit">{{ $t("activity.editProject") }}</span>
              <!-- Create Project -->
              <span v-else>{{ $t("activity.createProject") }}</span>
            </v-toolbar-title>
            <v-spacer />
            <!-- Cancel and Return -->
            <x-btn
              v-ge="['project', 'cancel']"
              :tooltip="$t('tooltip.cancelReturn')"
              to="/"
              class="elevation-20"
            >
              <!-- Cancel -->
              {{ $t("general.cancel") }}
            </x-btn>
            <x-btn
              v-ge="['project', 'save']"
              :disabled="!valid || !envStatusValid"
              class="primary"
              @click="createOrUpdateProject()"
            >
              <!-- Update & Restart -->
              <span v-if="edit">{{ $t("tooltip.updateRestart") }}</span>
              <!-- Save Project -->
              <span v-else>{{ $t("activity.saveProject") }}</span>
            </x-btn>
            <v-progress-linear
              v-if="projectReloading"
              top
              absolute
              color="success"
              indeterminate
              height="3"
              style="top: -3px"
            />
          </v-toolbar>

          <div ref="panelContainer" style="">
            <api-overlay
              v-show="projectReloading"
              :project-created="projectCreated"
            />
            <v-container fluid>
              <v-row>
                <v-col cols="12" class="mb-0 pb-0">
                  <div style="max-width: 360px" class="mx-auto mb-3">
                    <!-- Enter Project Name -->
                    <v-text-field
                      ref="name"
                      v-model="project.title"
                      v-ge="['project', 'name']"
                      :rules="form.titleValidationRule"
                      :height="20"
                      :label="$t('placeholder.projName')"
                      autofocus
                    />
                  </div>
                </v-col>

                <v-col
                  v-show="isTitle"
                  cols="10"
                  offset="1"
                  :class="{ 'mt-0 pt-0': !edit, 'mt-3 pt-3': edit }"
                >
                  <p
                    :class="{
                      'text-center mb-2 mt-3': !edit,
                      'text-center mb-2 mt-3 grey--text': edit,
                    }"
                  >
                    {{ $t("title.dbCredentials") }}
                  </p>
                  <v-expansion-panels
                    v-model="panel"
                    focusable
                    accordion=""
                    class="elevation-20"
                    style="border: 1px solid white"
                  >
                    <v-expansion-panel
                      v-for="(envData, envKey, panelIndex) in project.envs"
                      :key="panelIndex"
                      :ref="`panel${envKey}`"
                      @change="onPanelToggle(panelIndex, envKey)"
                    >
                      <v-expansion-panel-header disable-icon-rotate>
                        <p class="pa-0 ma-0">
                          <v-tooltip
                            v-for="(db, tabIndex) in envData.db"
                            :key="tabIndex"
                            bottom
                          >
                            <template #activator="{ on }">
                              <v-icon
                                small
                                :color="getDbStatusColor(db)"
                                @click.native.stop="
                                  showDBTabInEnvPanel(panelIndex, tabIndex)
                                "
                                v-on="on"
                              >
                                mdi-database
                              </v-icon>
                            </template>
                            {{ getDbStatusTooltip(db) }}
                          </v-tooltip>

                          <span
                            v-if="project.ui[envKey]"
                            class="caption"
                            :class="project.ui[envKey].color + '--text'"
                          >
                            <i>{{ project.ui[envKey].msg }}</i>
                          </span>

                          <x-btn
                            v-if="panelIndex"
                            v-ge="['project', 'env-delete']"
                            small
                            text
                            btn.class="float-right"
                            tooltip="Click here to remove environment"
                            @click.native.stop="removeEnv(envKey)"
                          >
                            <v-hover v-slot="{ hover }">
                              <v-icon
                                :color="hover ? 'error' : 'grey'"
                                @click.native.stop="removeEnv(envKey)"
                              >
                                mdi-delete
                              </v-icon>
                            </v-hover>
                          </x-btn>
                        </p>
                        <template #actions>
                          <v-tooltip
                            v-if="getEnvironmentStatusAggregated(envData.db)"
                            bottom
                          >
                            <template #activator="{ on }">
                              <v-icon color="green" v-on="on">
                                mdi-check-circle
                              </v-icon>
                            </template>
                            <span>Environment setup complete</span>
                          </v-tooltip>
                          <v-tooltip v-else-if="edit" bottom>
                            <template #activator="{ on }">
                              <v-icon color="orange" v-on="on">
                                mdi-alert-circle
                              </v-icon>
                            </template>
                            <span>Environment setup pending</span>
                          </v-tooltip>
                        </template>
                      </v-expansion-panel-header>
                      <v-expansion-panel-content eager>
                        <v-col>
                          <v-card flat="">
                            <v-tabs
                              v-model="databases[panelIndex]"
                              height="34"
                              background-color=""
                            >
                              <v-tab
                                v-for="(db, dbIndex) in project.envs[envKey].db"
                                :key="dbIndex"
                              >
                                <v-icon small>
                                  mdi-database
                                </v-icon> &nbsp;
                                <span class="text-capitalize caption">{{
                                  db.connection.database
                                }}</span>
                              </v-tab>
                              <v-tabs-items v-model="databases[panelIndex]">
                                <v-tab-item
                                  v-for="(db, dbIndex) in project.envs[envKey]
                                    .db"
                                  :key="dbIndex"
                                >
                                  <v-card flat>
                                    <!--                            <form ref="form" class="pa-3">-->
                                    <v-container class="justify-center">
                                      <v-row style="position: relative">
                                        <v-overlay
                                          v-if="showMonaco[dbIndex]"
                                          absolute
                                          class="monaco-overlay"
                                        >
                                          <v-container fluid class="h-100">
                                            <v-card
                                              style="position: relative"
                                              class="h-100"
                                            >
                                              <v-icon
                                                class="monaco-overlay-close pointer"
                                                color="error"
                                                @click="
                                                  $set(
                                                    showMonaco,
                                                    dbIndex,
                                                    false
                                                  )
                                                "
                                              >
                                                mdi-close-circle
                                              </v-icon>

                                              <span
                                                class="ml-2 caption grey--text"
                                              >Refer knex documentation
                                                <a
                                                  href="https://knexjs.org/#Installation-client"
                                                  target="_blank"
                                                  class="grey--text"
                                                >here</a>
                                                .</span>

                                              <monaco-json-object-editor
                                                v-model="
                                                  project.envs[envKey].db[
                                                    dbIndex
                                                  ]
                                                "
                                                style="
                                                  height: calc(100% - 20px);
                                                  width: 100%;
                                                "
                                              />
                                            </v-card>
                                          </v-container>
                                        </v-overlay>

                                        <v-col cols="4" class="py-0">
                                          <!-- Database Type -->
                                          <v-select
                                            v-model="client[dbIndex]"
                                            v-ge="['project', 'env-db-change']"
                                            class="body-2 db-select"
                                            :items="Object.keys(databaseNames)"
                                            :label="$t('labels.dbType')"
                                            @change="
                                              onDatabaseTypeChanged(
                                                client[dbIndex],
                                                db,
                                                dbIndex,
                                                envKey
                                              )
                                            "
                                          >
                                            <template #selection="{ item }">
                                              <v-chip
                                                small
                                                :color="
                                                  colors[
                                                    Object.keys(
                                                      databaseNames
                                                    ).indexOf(item) %
                                                    colors.length
                                                  ]
                                                "
                                                class=""
                                              >
                                                {{ item }}
                                              </v-chip>
                                            </template>

                                            <template
                                              slot="item"
                                              slot-scope="data"
                                            >
                                              <v-chip
                                                :color="
                                                  colors[
                                                    Object.keys(
                                                      databaseNames
                                                    ).indexOf(data.item) %
                                                    colors.length
                                                  ]
                                                "
                                                class="caption"
                                              >
                                                {{ data.item }}
                                              </v-chip>
                                            </template>
                                          </v-select>
                                        </v-col>
                                        <!-- SQLite File -->
                                        <v-col
                                          v-if="db.client === 'sqlite3'"
                                          class="py-0"
                                        >
                                          <v-text-field
                                            v-model="
                                              db.connection.connection.filename
                                            "
                                            v-ge="['project', 'env-db-file']"
                                            :rules="form.folderRequiredRule"
                                            :label="$t('labels.sqliteFile')"
                                            @click="selectSqliteFile(db)"
                                          >
                                            <v-icon slot="prepend" color="info">
                                              mdi-file-outline
                                            </v-icon>
                                          </v-text-field>
                                        </v-col>
                                        <!-- Host Address -->
                                        <v-col
                                          v-if="db.client !== 'sqlite3'"
                                          cols="4"
                                          class="py-0"
                                        >
                                          <v-text-field
                                            v-model="db.connection.host"
                                            v-ge="['project', 'env-db-host']"
                                            class="body-2"
                                            :rules="form.requiredRule"
                                            :label="$t('labels.hostAddress')"
                                          />
                                        </v-col>
                                        <!-- Port Number -->
                                        <v-col
                                          v-if="db.client !== 'sqlite3'"
                                          cols="4"
                                          class="py-0"
                                        >
                                          <v-text-field
                                            v-model="db.connection.port"
                                            v-ge="['project', 'env-db-port']"
                                            class="body-2"
                                            :label="$t('labels.port')"
                                            :rules="form.portValidationRule"
                                          />
                                        </v-col>
                                        <!-- Username -->
                                        <v-col
                                          v-if="db.client !== 'sqlite3'"
                                          cols="4"
                                          class="py-0"
                                        >
                                          <v-text-field
                                            v-model="db.connection.user"
                                            v-ge="['project', 'env-db-user']"
                                            class="body-2"
                                            :rules="form.requiredRule"
                                            :label="$t('labels.username')"
                                          />
                                        </v-col>
                                        <!-- Password -->
                                        <v-col
                                          v-if="db.client !== 'sqlite3'"
                                          cols="4"
                                          class="py-0"
                                        >
                                          <v-text-field
                                            :ref="`password${envKey}`"
                                            v-model="db.connection.password"
                                            v-ge="[
                                              'project',
                                              'env-db-password',
                                            ]"
                                            class="body-2 db-password"
                                            :type="
                                              showPass[
                                                `${panelIndex}_${dbIndex}`
                                              ]
                                                ? 'text'
                                                : 'password'
                                            "
                                            :label="$t('labels.password')"
                                            @dblclick="enableDbEdit++"
                                          >
                                            <template #append>
                                              <v-icon
                                                small
                                                @click="
                                                  $set(
                                                    showPass,
                                                    `${panelIndex}_${dbIndex}`,
                                                    !showPass[
                                                      `${panelIndex}_${dbIndex}`
                                                    ]
                                                  )
                                                "
                                              >
                                                {{
                                                  showPass[
                                                    `${panelIndex}_${dbIndex}`
                                                  ]
                                                    ? "visibility_off"
                                                    : "visibility"
                                                }}
                                              </v-icon>
                                            </template>
                                          </v-text-field>
                                        </v-col>
                                        <!-- Database : create if not exists -->
                                        <v-col
                                          v-if="db.client !== 'sqlite3'"
                                          cols="4"
                                          class="py-0"
                                        >
                                          <v-text-field
                                            v-model="db.connection.database"
                                            v-ge="['project', 'env-db-name']"
                                            :disabled="edit && enableDbEdit < 2"
                                            class="body-2 database-field"
                                            :rules="form.requiredRule"
                                            :label="
                                              $t('labels.dbCreateIfNotExists')
                                            "
                                          />
                                        </v-col>
                                        <!--  todo : Schema name -->
                                        <v-col
                                          v-if="db.client === 'mssql' || db.client === 'pg'"
                                          cols="4"
                                          class="py-0"
                                        >
                                          <v-text-field
                                            v-model="schema"
                                            :disabled="edit && enableDbEdit < 2"
                                            class="body-2 database-field"
                                            :rules="form.requiredRule"
                                            :label="
                                              $t('labels.schemaName')
                                            "
                                          />
                                        </v-col>
                                        <!--  todo : ssl & inflection -->
                                        <v-col
                                          v-if="db.client !== 'sqlite3'"
                                          cols="12"
                                          class=""
                                        >
                                          <v-expansion-panels>
                                            <v-expansion-panel
                                              style="border: 1px solid wheat"
                                            >
                                              <v-expansion-panel-header>
                                                <!-- SSL & Advanced parameters -->
                                                <span
                                                  class="grey--text caption"
                                                >{{
                                                  $t(
                                                    "title.advancedParameters"
                                                  )
                                                }}</span>
                                              </v-expansion-panel-header>
                                              <v-expansion-panel-content>
                                                <v-card class="elevation-0">
                                                  <v-card-text>
                                                    <v-select
                                                      v-model="db.ui.sslUse"
                                                      class="caption"
                                                      :items="
                                                        Object.keys(sslUsage)
                                                      "
                                                    >
                                                      <template
                                                        #item="{ item }"
                                                      >
                                                        <span class="caption">{{
                                                          item
                                                        }}</span>
                                                      </template>
                                                    </v-select>

                                                    <v-row class="pa-0 ma-0">
                                                      <input
                                                        ref="certFilePath"
                                                        type="file"
                                                        class="d-none"
                                                        @change="
                                                          readFileContent(
                                                            db,
                                                            'ssl',
                                                            'cert',
                                                            dbIndex
                                                          )
                                                        "
                                                      >
                                                      <!-- Select .cert file -->
                                                      <x-btn
                                                        v-ge="[
                                                          'project',
                                                          'env-db-cert',
                                                        ]"
                                                        :tooltip="
                                                          $t(
                                                            'tooltip.clientCert'
                                                          )
                                                        "
                                                        small
                                                        color="primary"
                                                        outlined
                                                        class="elevation-5"
                                                        @click="
                                                          selectFile(
                                                            db,
                                                            'ssl',
                                                            'certFilePath',
                                                            dbIndex
                                                          )
                                                        "
                                                      >
                                                        {{ db.ui.ssl.cert }}
                                                      </x-btn>
                                                      <!-- Select .key file -->
                                                      <input
                                                        ref="keyFilePath"
                                                        type="file"
                                                        class="d-none"
                                                        @change="
                                                          readFileContent(
                                                            db,
                                                            'ssl',
                                                            'key',
                                                            dbIndex
                                                          )
                                                        "
                                                      >
                                                      <x-btn
                                                        v-ge="[
                                                          'project',
                                                          'env-db-key',
                                                        ]"
                                                        :tooltip="
                                                          $t(
                                                            'tooltip.clientKey'
                                                          )
                                                        "
                                                        small
                                                        color="primary"
                                                        outlined
                                                        class="elevation-5"
                                                        @click="
                                                          selectFile(
                                                            db,
                                                            'ssl',
                                                            'keyFilePath',
                                                            dbIndex
                                                          )
                                                        "
                                                      >
                                                        {{ db.ui.ssl.key }}
                                                      </x-btn>
                                                      <!-- Select CA file -->
                                                      <input
                                                        ref="caFilePath"
                                                        type="file"
                                                        class="d-none"
                                                        @change="
                                                          readFileContent(
                                                            db,
                                                            'ssl',
                                                            'ca',
                                                            dbIndex
                                                          )
                                                        "
                                                      >
                                                      <x-btn
                                                        v-ge="[
                                                          'project',
                                                          'env-db-ca',
                                                        ]"
                                                        :tooltip="
                                                          $t('tooltip.clientCA')
                                                        "
                                                        small
                                                        color="primary"
                                                        outlined
                                                        @click="
                                                          selectFile(
                                                            db,
                                                            'ssl',
                                                            'caFilePath',
                                                            dbIndex
                                                          )
                                                        "
                                                      >
                                                        {{ db.ui.ssl.ca }}
                                                      </x-btn>
                                                    </v-row>

                                                    <v-row>
                                                      <v-col>
                                                        <!-- Inflection - Table name -->
                                                        <v-select
                                                          v-model="
                                                            db.meta.inflection
                                                              .table_name
                                                          "
                                                          :disabled="edit"
                                                          class="caption"
                                                          :label="
                                                            $t(
                                                              'labels.inflection.tableName'
                                                            )
                                                          "
                                                          :items="
                                                            project.projectType ===
                                                              'rest'
                                                              ? [
                                                                'camelize',
                                                                'none',
                                                              ]
                                                              : ['camelize']
                                                          "
                                                        >
                                                          <template
                                                            #item="{ item }"
                                                          >
                                                            <span
                                                              class="caption"
                                                            >{{ item }}</span>
                                                          </template>
                                                        </v-select>
                                                      </v-col>
                                                      <v-col>
                                                        <!-- Inflection - Column name -->
                                                        <v-select
                                                          v-model="
                                                            db.meta.inflection
                                                              .column_name
                                                          "
                                                          :disabled="edit"
                                                          class="caption"
                                                          :label="
                                                            $t(
                                                              'labels.inflection.columnName'
                                                            )
                                                          "
                                                          :items="
                                                            project.projectType ===
                                                              'rest'
                                                              ? [
                                                                'camelize',
                                                                'none',
                                                              ]
                                                              : ['camelize']
                                                          "
                                                        >
                                                          <template
                                                            #item="{ item }"
                                                          >
                                                            <span
                                                              class="caption"
                                                            >{{ item }}</span>
                                                          </template>
                                                        </v-select>
                                                      </v-col>
                                                      <v-col
                                                        class="d-flex align-center flex-shrink-1 flex-grow-0"
                                                      >
                                                        <x-btn
                                                          small
                                                          btn.class="text-capitalize"
                                                          :tooltip="
                                                            $t(
                                                              'activity.editConnJson'
                                                            )
                                                          "
                                                          outlined
                                                          @click="
                                                            $set(
                                                              showMonaco,
                                                              dbIndex,
                                                              !showMonaco[
                                                                dbIndex
                                                              ]
                                                            )
                                                          "
                                                        >
                                                          <v-icon
                                                            small
                                                            class="mr-1"
                                                          >
                                                            mdi-database-edit
                                                          </v-icon>
                                                          <!-- Edit connection JSON -->
                                                          {{
                                                            $t(
                                                              "activity.editConnJson"
                                                            )
                                                          }}
                                                        </x-btn>
                                                      </v-col>
                                                    </v-row>
                                                  </v-card-text>
                                                </v-card>
                                              </v-expansion-panel-content>
                                            </v-expansion-panel>
                                          </v-expansion-panels>
                                        </v-col>
                                      </v-row>

                                      <v-row class="text-right justify-end">
                                        <!-- Test Database Connection -->
                                        <x-btn
                                          v-ge="[
                                            'project',
                                            'env-db-test-connection',
                                          ]"
                                          :tooltip="$t('activity.testDbConn')"
                                          outlined
                                          small
                                          @click="
                                            testConnection(
                                              db,
                                              envKey,
                                              panelIndex
                                            )
                                          "
                                        >
                                          <!-- Test Database Connection -->
                                          {{ $t("activity.testDbConn") }}
                                        </x-btn>
                                        <!-- Remove Database from environment -->
                                        <x-btn
                                          v-if="dbIndex"
                                          v-ge="['project', 'env-db-delete']"
                                          :tooltip="
                                            $t('activity.removeDbFromEnv')
                                          "
                                          text
                                          small
                                          @click="
                                            removeDBFromEnv(
                                              db,
                                              envKey,
                                              panelIndex,
                                              dbIndex
                                            )
                                          "
                                        >
                                          <v-hover v-slot="{ hover }">
                                            <v-icon
                                              :color="hover ? 'error' : 'grey'"
                                            >
                                              mdi-database-remove
                                            </v-icon>
                                          </v-hover>
                                        </x-btn>
                                      </v-row>
                                    </v-container>
                                    <!--                            </form>-->
                                  </v-card>
                                </v-tab-item>
                              </v-tabs-items>
                            </v-tabs>
                          </v-card>
                        </v-col>
                      </v-expansion-panel-content>
                    </v-expansion-panel>
                  </v-expansion-panels>
                </v-col>
              </v-row>
            </v-container>
          </div>
        </v-card>
      </v-form>
    </v-col>
    <dlgOk
      v-if="dialog.show"
      :dialog-show="dialog.show"
      :mtd-ok="dialog.mtdOk"
      :heading="dialog.heading"
      :type="dialog.type"
    />

    <!-- heading="Connection was successful" -->
    <!-- ok-label="Ok & Save Project" -->
    <dlg-ok-new
      v-model="testSuccess"
      :heading="$t('msg.info.dbConnected')"
      :ok-label="$t('activity.OkSaveProject')"
      type="success"
      :btn-attr="{ small: false }"
      @ok="createOrUpdateProject"
    />

    <textDlgSubmitCancel
      v-if="dialogGetEnvName.dialogShow"
      :dialog-show="dialogGetEnvName.dialogShow"
      :heading="dialogGetEnvName.heading"
      :mtd-dialog-submit="mtdDialogGetEnvNameSubmit"
      :mtd-dialog-cancel="mtdDialogGetEnvNameCancel"
    />

    <div v-if="isTitle && !edit" class="floating-button">
      <v-tooltip top>
        <template #activator="{ on }">
          <v-btn
            v-ge="['project', 'save']"
            fab
            dark
            large
            tooltip="Scroll to top"
            :disabled="!valid || !envStatusValid"
            class="primary"
            v-on="on"
            @click="createOrUpdateProject()"
          >
            <v-icon>save</v-icon>
          </v-btn>
        </template>
        <span> Save Project </span>
      </v-tooltip>
    </div>
  </v-container>
</template>
<script>
import JSON5 from 'json5'

import { mapGetters, mapActions } from 'vuex'
import Vue from 'vue'

import { v4 as uuidv4 } from 'uuid'

import XBtn from './global/XBtn'
import dlgOk from './utils/DlgOk.vue'
import textDlgSubmitCancel from './utils/DlgTextSubmitCancel'
import MonacoJsonObjectEditor from '@/components/monaco/MonacoJsonObjectEditor'
import ApiOverlay from '~/components/ApiOverlay'
import colors from '@/mixins/colors'
import DlgOkNew from '~/components/utils/DlgOkNew'
import readFile from '@/helpers/fileReader'

const {
  uniqueNamesGenerator,
  starWars,
  adjectives,
  animals
} = require('unique-names-generator')

const homeDir = ''

export default {
  components: {
    DlgOkNew,
    ApiOverlay,
    MonacoJsonObjectEditor,
    XBtn,
    dlgOk,
    textDlgSubmitCancel
  },
  mixins: [colors],
  layout: 'empty',
  data() {
    return {
      schema: 'public',
      testSuccess: false,
      projectCreated: false,
      allSchemas: false,
      showMonaco: [],
      smtpConfiguration: {
        from: '',
        options: ''
      },
      showSecret: false,
      loaderMessages: [
        'Setting up new database configs',
        'Inferring database schema',
        'Generating APIs.',
        'Generating APIs..',
        'Generating APIs...',
        'Generating APIs....',
        'Please wait',
        'Please wait.',
        'Please wait..',
        'Please wait...',
        'Please wait..',
        'Please wait.',
        'Please wait',
        'Please wait.',
        'Please wait..',
        'Please wait...',
        'Please wait..',
        'Please wait.',
        'Please wait..',
        'Please wait...'
      ],
      loaderMessage: '',
      projectReloading: false,
      enableDbEdit: 0,
      authTypes: [
        {
          text: 'JWT',
          value: 'jwt'
        },
        {
          text: 'Master Key',
          value: 'masterKey'
        },
        {
          text: 'Middleware',
          value: 'middleware'
        },
        {
          text: 'Disabled',
          value: 'none'
        }
      ],
      projectTypes: [
        {
          text: 'REST APIs',
          value: 'rest',
          icon: 'mdi-code-json',
          iconColor: 'green'
        },
        {
          text: 'GRAPHQL APIs',
          value: 'graphql',
          icon: 'mdi-graphql',
          iconColor: 'pink'
        }
      ],

      showPass: {},
      /** ************** START : form related ****************/
      form: {
        portValidationRule: [v => /^\d+$/.test(v) || 'Not a valid port'],
        titleValidationRule: [
          v => !!v || 'Title is required',
          v => v.length <= 50 || 'Project name exceeds 50 characters',
        ],
        requiredRule: [v => !!v || 'Field is required'],
        folderRequiredRule: [v => !!v || 'Folder path is required']
      },
      valid: null,
      panel: 0,
      client: ['Sqlite'],
      baseFolder: homeDir,

      tab: null,
      env: null,
      databases: [],
      /** ************** END : form related ****************/
      auth: {
        authSecret: uuidv4(),
        authType: 'jwt',
        webhook: null
      },
      project: {},
      defaultProject: {
        title: '',
        version: '0.6',
        folder: homeDir,
        envs: {
          _noco: {
            db: [
              {
                client: 'pg',
                connection: {
                  host: 'localhost',
                  port: '5432',
                  user: 'postgres',
                  password: 'password',
                  database: '_dev',
                  ssl: {
                    ca: '',
                    key: '',
                    cert: ''
                  }
                },
                searchPath: ['public'],
                meta: {
                  tn: 'nc_evolutions',
                  dbAlias: 'db',
                  api: {
                    type: 'rest',
                    prefix: '',
                    graphqlDepthLimit: 10
                  },
                  inflection: {
                    table_name: 'camelize',
                    column_name: 'camelize'
                  }
                },
                ui: {
                  setup: -1,
                  ssl: {
                    key: this.$t('labels.clientKey'), // Client Key
                    cert: this.$t('labels.clientCert'), // Client Cert
                    ca: this.$t('labels.serverCA') // Server CA
                  },
                  sslUse: 'Preferred'
                }
              }
            ],
            apiClient: {
              data: []
            }
          }
        },
        workingEnv: '_noco',
        ui: {
          envs: {
            _noco: {}
          }
        },
        meta: {
          version: '0.6',
          seedsFolder: 'seeds',
          queriesFolder: 'queries',
          apisFolder: 'apis',
          projectType: 'rest',
          type: 'mvc',
          language: 'ts'
        },
        seedsFolder: 'seeds',
        queriesFolder: 'queries',
        apisFolder: 'apis',
        projectType: 'rest',
        type: 'mvc',
        language: 'ts',
        apiClient: {
          data: []
        }
      },

      sampleConnectionData: {
        Postgres: {
          host: 'localhost',
          port: '5432',
          user: 'postgres',
          password: 'password',
          database: '_test',
          ssl: {
            ca: '',
            key: '',
            cert: ''
          }
        },
        MySQL: {
          host: 'localhost',
          port: '3306',
          user: 'root',
          password: 'password',
          database: '_test',
          ssl: {
            ca: '',
            key: '',
            cert: ''
          }
        },
        Vitess: {
          host: 'localhost',
          port: '15306',
          user: 'root',
          password: 'password',
          database: '_test',
          ssl: {
            ca: '',
            key: '',
            cert: ''
          }
        },
        TiDB: {
          host: 'localhost',
          port: '4000',
          user: 'root',
          password: '',
          database: '_test',
          ssl: {
            ca: '',
            key: '',
            cert: ''
          }
        },
        Yugabyte: {
          host: 'localhost',
          port: '5432',
          user: 'postgres',
          password: '',
          database: '_test',
          ssl: {
            ca: '',
            key: '',
            cert: ''
          }
        },
        CitusDB: {
          host: 'localhost',
          port: '5432',
          user: 'postgres',
          password: '',
          database: '_test',
          ssl: {
            ca: '',
            key: '',
            cert: ''
          }
        },
        CockroachDB: {
          host: 'localhost',
          port: '5432',
          user: 'postgres',
          password: '',
          database: '_test',
          ssl: {
            ca: '',
            key: '',
            cert: ''
          }
        },
        Greenplum: {
          host: 'localhost',
          port: '5432',
          user: 'postgres',
          password: '',
          database: '_test',
          ssl: {
            ca: '',
            key: '',
            cert: ''
          }
        },
        MsSQL: {
          host: 'localhost',
          port: 1433,
          user: 'sa',
          password: 'Password123.',
          database: '_test',
          ssl: {
            ca: '',
            key: '',
            cert: ''
          }
        },
        Oracle: {
          host: 'localhost',
          port: '1521',
          user: 'system',
          password: 'Oracle18',
          database: '_test',
          ssl: {
            ca: '',
            key: '',
            cert: ''
          }
        },
        Sqlite: {
          client: 'sqlite3',
          database: homeDir,
          connection: {
            filename: homeDir
          },
          useNullAsDefault: true
        }
      },
      dialog: {
        show: false,
        title: '',
        heading: '',
        mtdOk: this.testConnectionMethodSubmit,
        type: 'primary'
      },
      // TODO: apply i18n for sslUsage
      // See general.no - 5 in en.json
      sslUsage: {
        No: 'No',
        Preferred: 'Preferred',
        Required: 'pg',
        'Required-CA': 'Required-CA',
        'Required-IDENTITY': 'Required-IDENTITY'
      },
      sslUse: this.$t('general.preferred'), // Preferred
      ssl: {
        key: this.$t('labels.clientKey'), // Client Key
        cert: this.$t('labels.clientCert'), // Client Cert
        ca: this.$t('labels.serverCA') // Server CA
      },
      databaseNames: {
        MySQL: 'mysql2',
        Postgres: 'pg',
        // Oracle: "oracledb",
        MsSQL: 'mssql',
        Sqlite: 'sqlite3'
        // Vitess: "mysql2",
        // TiDB: "mysql2",
        // Yugabyte: "pg",
        // CitusDB: "pg",
        // CockroachDB: "pg",
        // Greenplum: "pg"
      },
      testDatabaseNames: {
        mysql2: null,
        mysql: null,
        pg: 'postgres',
        oracledb: 'xe',
        mssql: undefined,
        sqlite3: 'a.sqlite'
      },
      dbIcons: {
        Oracle: 'temp/db/oracle.png',
        Postgres: 'temp/db/postgre.png',
        MySQL: 'temp/db/mysql.png',
        MsSQL: 'temp/db/mssql.png',
        Sqlite: 'temp/db/sqlite.svg',
        Salesforce: 'temp/salesforce-3-569548.webp',
        SAP: 'temp/sap.png',
        Stripe: 'temp/stripe.svg'
      },
      dialogGetEnvName: {
        dialogShow: false,
        heading: 'Enter New Environment Name',
        field: 'Environment Name'
      },

      compErrorMessages: [
        this.$t('msg.error.invalidChar'), // Invalid character in folder path
        this.$t('msg.error.invalidDbCredentials'), // Invalid database credentials
        this.$t('msg.error.unableToConnectToDb'), // Unable to connect to database, please check your database is up
        this.$t('msg.error.userDoesntHaveSufficientPermission') // User does not exist or have sufficient permission to create schema
      ],
      compErrorMessage: ''
    }
  },
  computed: {
    ...mapGetters({ sqlMgr: 'sqlMgr/sqlMgr' }),
    isTitle() {
      return this.project.title && this.project.title.trim().length
    },
    envStatusValid() {
      return (
        this.project.envs &&
        Object.values(this.project.envs).every(
          this.getEnvironmentStatusAggregatedNew
        )
      )
    },
    typeIcon() {
      if (this.project.projectType) {
        return this.projectTypes.find(
          ({ value }) => value === this.project.projectType
        )
      } else {
        return {
          icon: 'mdi-server',
          iconColor: 'primary'
        }
      }
    },
    databaseNamesReverse() {
      return Object.entries(this.databaseNames).reduce(
        (newObj, [value, key]) => {
          newObj[key] = value
          return newObj
        },
        {}
      )
    }
  },
  methods: {
    async enableAllSchemas() {
      this.$toast.info('Enabled all schemas').goAway(3000)
      this.allSchemas = true
      await this.$axios({
        url: 'demo',
        baseURL: `${this.$axios.defaults.baseURL}/dashboard`
      })
    },

    ...mapActions({
      loadProjects: 'project/loadProjects'
    }),
    onAdvancePanelToggle() {
      if (this.$refs.monacoEditor) {
        setTimeout(() => this.$refs.monacoEditor.resizeLayout(), 400)
      }
    },
    getProjectEditTooltip() {
      // return `Opens ${path.join(this.project.folder, 'config.xc.json')} and edit - its really simple`;
    },
    openJsonInSystemEditor() {
      // shell.openItem(path.join(this.project.folder, 'config.xc.json'));
    },
    readFileContent(db, obj, key, index) {
      readFile(this.$refs[`${key}FilePath`][index], (data) => {
        Vue.set(db.connection[obj], key, data)
      })
    },
    selectFile(db, obj, key, index) {
      this.$refs[key][index].click()
    },
    onPanelToggle(panelIndex, envKey) {
      this.$nextTick(() => {
        if (this.panel !== undefined) {
          const panelContainer = this.$refs.panelContainer
          const panel = this.$refs[`panel${envKey}`][0].$el
          setTimeout(
            () =>
              (panelContainer.scrollTop =
                panel.getBoundingClientRect().top +
                panelContainer.scrollTop -
                panelContainer.getBoundingClientRect().top -
                50),
            500
          )
          setTimeout(() => this.$refs[`password${envKey}`][0].focus())
        }
      })
    },
    scrollToTop() {
      document.querySelector('html').scrollTop = 0
    },
    showDBTabInEnvPanel(panelIndex, tabIndex) {
      this.panel = panelIndex
      Vue.set(this.databases, panelIndex, tabIndex)
    },
    getProjectJson() {
      /**
       * remove UI keys within project
       */
      const xcConfig = JSON.parse(JSON.stringify(this.project))
      delete xcConfig.ui

      for (const env in xcConfig.envs) {
        for (let i = 0; i < xcConfig.envs[env].db.length; ++i) {
          xcConfig.envs[env].db[i].meta.api.type = this.project.projectType
          if (
            xcConfig.envs[env].db[i].client === 'mysql' ||
            xcConfig.envs[env].db[i].client === 'mysql2'
          ) {
            xcConfig.envs[env].db[i].connection.multipleStatements = true
          }
          this.handleSSL(xcConfig.envs[env].db[i], false)
          delete xcConfig.envs[env].db[i].ui
          if (this.client[i] === 'Vitess') {
            xcConfig.envs[env].db[i].meta.dbtype = 'vitess'
          }
          if (this.client[i] === 'TiDB') {
            xcConfig.envs[env].db[i].meta.dbtype = 'tidb'
          }
          if (xcConfig.envs[env].db[i].client === 'oracledb') {
            xcConfig.envs[env].db[i].pool = {
              min: 0,
              max: 50
            }

            xcConfig.envs[env].db[i].acquireConnectionTimeout = 60000
          }

          const inflectionObj = xcConfig.envs[env].db[i].meta.inflection

          if (inflectionObj) {
            if (Array.isArray(inflectionObj.table_name)) {
              inflectionObj.table_name = inflectionObj.table_name.join(',')
            }
            if (Array.isArray(inflectionObj.column_name)) {
              inflectionObj.column_name = inflectionObj.column_name.join(',')
            }

            inflectionObj.table_name = inflectionObj.table_name || 'none'
            inflectionObj.column_name = inflectionObj.column_name || 'none'
          }

          if (this.allSchemas) {
            delete xcConfig.envs[env].db[i].connection.database
            xcConfig.envs[env].db[i].meta.allSchemas = true
          }
        }
      }

      xcConfig.auth = {}
      switch (this.auth.authType) {
        case 'jwt':
          xcConfig.auth.jwt = {
            secret: this.auth.authSecret,
            dbAlias:
            xcConfig.envs[Object.keys(xcConfig.envs)[0]].db[0].meta.dbAlias
          }
          break
        case 'masterKey':
          xcConfig.auth.masterKey = {
            secret: this.auth.authSecret
          }
          sessionStorage.setItem('masterKey', this.auth.authSecret)
          break
        case 'middleware':
          xcConfig.auth.masterKey = {
            url: this.auth.webhook
          }
          break
        default:
          this.auth.disabled = true
          break
      }

      xcConfig.type = this.$store.state.project.appInfo
        ? this.$store.state.project.appInfo.type
        : 'docker'

      if (
        this.smtpConfiguration &&
        this.smtpConfiguration.from &&
        this.smtpConfiguration.options.trim()
      ) {
        try {
          xcConfig.mailer = {
            options: JSON5.parse(this.smtpConfiguration.options),
            from: this.smtpConfiguration.from
          }
        } catch (e) {
        }
      }

      xcConfig.meta = xcConfig.meta || {}
      xcConfig.meta.db = {
        client: 'sqlite3',
        connection: {
          filename: 'xc.db'
        }
      }

      return xcConfig
    },

    constructProjectJsonFromProject(project) {
      const p = project // JSON.parse(JSON.stringify(project.projectJson));

      p.ui = {
        envs: {
          _noco: {}
        }
      }
      for (const env in p.envs) {
        let i = 0
        for (const db of p.envs[env].db) {
          Vue.set(this.client, i++, this.databaseNamesReverse[db.client])

          Vue.set(db, 'ui', {
            setup: 0,
            ssl: {
              key: this.$t('labels.clientKey'), // Client Key
              cert: this.$t('labels.clientCert'), // Client Cert
              ca: this.$t('labels.serverCA') // Server CA
            },
            sslUse: this.$t('general.preferred') // Preferred
          })
        }
      }
      // delete p.projectJson;

      if (p.auth) {
        if (p.auth.jwt) {
          this.auth.authType = 'jwt'
          this.auth.authSecret = p.auth.jwt.secret
        } else if (p.auth.masterKey) {
          if (p.auth.masterKey.secret) {
            this.auth.authSecret = p.auth.masterKey.secret
            this.auth.authType = 'masterKey'
          } else if (p.auth.masterKey.url) {
            this.auth.webhook = p.auth.masterKey.url
            this.auth.authType = 'middleware'
          } else {
            this.auth.authType = 'none'
          }
        } else {
          this.auth.authType = 'none'
        }
      } else {
        this.auth.authType = 'none'
      }

      this.project = p
      if (p.mailer) {
        this.smtpConfiguration = {
          from: p.mailer.from,
          options: JSON.stringify(p.mailer.options, 0, 2)
        }
      }
      delete p.mailer
    },

    async createOrUpdateProject() {
      const projectJson = this.getProjectJson()
      delete projectJson.folder

      let i = 0
      const toast = this.$toast.info(this.loaderMessages[0])
      const interv = setInterval(() => {
        if (this.edit) {
          return
        }
        if (i < this.loaderMessages.length - 1) {
          i++
        }
        if (toast) {
          if (!this.allSchemas) {
            toast.text(this.loaderMessages[i])
          } else {
            toast.goAway(100)
          }
        }
      }, 1000)

      this.projectReloading = true

      const con = projectJson.envs._noco.db[0]
      if (con.client === 'pg' || con.client === 'mssql') {
        con.searchPath = [this.schema]
      } else if ('searchPath' in con) {
        delete con.searchPath
      }

      const inflection = (con.meta && con.meta.inflection) || {}
      try {
        const result = await this.$api.project.create({
          title: projectJson.title,
          bases: [
            {
              type: con.client,
              config: con,
              inflection_column: inflection.column_name,
              inflection_table: inflection.table_name
            }
          ],
          external: true
        })

        clearInterval(interv)
        toast.goAway(100)

        await this.$store.dispatch('project/ActLoadProjectInfo')

        this.projectReloading = false

        if (!this.edit && !this.allSchemas) {
          this.$router.push({
            path: `/nc/${result.id}`,
            query: {
              new: 1
            }
          })
        }

        this.projectCreated = true
      } catch (e) {
        this.$toast
          .error(await this._extractSdkResponseErrorMsg(e))
          .goAway(3000)
        toast.goAway(0)
      }

      this.projectReloading = false
      this.$e('a:project:create:extdb')
    },

    mtdDialogGetEnvNameSubmit(envName, cookie) {
      this.dialogGetEnvName.dialogShow = false
      if (envName in this.project.envs) {
      } else {
        Vue.set(this.project.envs, envName, {
          db: [
            {
              client: 'pg',
              connection: {
                host: 'localhost',
                port: '5432',
                user: 'postgres',
                password: 'password',
                database: 'new_database'
              },
              meta: {
                tn: 'nc_evolutions',
                dbAlias: 'db',
                inflection: {
                  table_name: 'camelize',
                  column_name: 'camelize'
                },
                api: {
                  type: ''
                }
              },
              ui: {
                setup: 0,
                ssl: {
                  key: this.$t('labels.clientKey'), // Client Key
                  cert: this.$t('labels.clientCert'), // Client Cert
                  ca: this.$t('labels.serverCA') // Server CA
                },
                sslUse: this.$t('general.preferred') // Preferred
              }
            }
          ],
          apiClient: { data: [] }
        })
      }
    },
    mtdDialogGetEnvNameCancel() {
      this.dialogGetEnvName.dialogShow = false
    },

    addNewEnvironment() {
      this.dialogGetEnvName.dialogShow = true
    },
    addNewDB(envKey, panelIndex) {
      const len = this.project.envs[envKey].db.length
      // eslint-disable-next-line no-unused-vars
      const lastDbName = `${this.project.title}_${envKey}_${len}`
      const dbType = (this.client[len] =
        this.client[len] || this.client[len - 1])
      const newlyCreatedIndex = this.project.envs[envKey].db.length
      const dbAlias =
        this.project.envs[envKey].db.length <= 0
          ? 'db'
          : `db${this.project.envs[envKey].db.length + 1}`
      this.project.envs[envKey].db.push({
        client: this.databaseNames[dbType],
        connection: {
          ...this.sampleConnectionData[dbType],
          database: `${this.project.title}_${envKey}_${newlyCreatedIndex + 1}`
        },
        meta: {
          tn: 'nc_evolutions',
          dbAlias,
          inflection: {
            table_name: 'camelize',
            column_name: 'camelize'
          },
          api: {
            type: ''
          }
        },
        ui: {
          setup: 0,
          sslUse: this.$t('general.preferred'), // Preferred
          ssl: {
            key: this.$t('labels.clientKey'), // Client Key
            cert: this.$t('labels.clientCert'), // Client Cert
            ca: this.$t('labels.serverCA') // Server CA
          }
        }
      })
      // set active tab as newly created
      this.databases[panelIndex] = newlyCreatedIndex
    },

    testConnectionMethodSubmit() {
      this.dialog.show = false
    },
    selectDir(ev) {
    },
    selectSqliteFile(db) {
    },

    getDbStatusColor(db) {
      switch (db.ui.setup) {
        case -1:
          return 'red'

        case 0:
          return 'orange'

        case 1:
          return 'green'

        default:
          break
      }
    },

    getDbStatusTooltip(db) {
      switch (db.ui.setup) {
        case -1:
          return 'DB Connection NOT successful'

        case 0:
          return 'MySql Database Detected - Test your connection'

        case 1:
          return 'DB Connection successful'

        default:
          break
      }
    },
    async newTestConnection(db, env, panelIndex) {
      if (
        db.connection.host === 'localhost' &&
        !this.edit &&
        env === '_noco' &&
        this.project.envs[env].db.length === 1 &&
        this.project.envs[env].db[0].connection.user === 'postgres' &&
        this.project.envs[env].db[0].connection.database ===
        `${this.project.title}_${env}_${this.project.envs[env].length}`
      ) {
        this.handleSSL(db)
        if (db.client === 'sqlite3') {
          db.ui.setup = 1
        } else {
          const c1 = {
            connection: {
              ...db.connection,
              ...(db.client !== 'pg'
                ? { database: this.testDatabaseNames[db.client] }
                : {})
            },
            client: db.client
          }

          const result = await this.$store.dispatch('sqlMgr/ActSqlOp', [
            {
              query: {
                skipProjectHasDb: 1
              }
            },
            'testConnection',
            c1
          ])

          if (result.code === 0) {
            db.ui.setup = 1
            let passed = true
            /**
             * get other environments
             * and if host is localhost - test and update connection status
             * UI panel close
             */

            for (const e in this.project.envs) {
              if (e === env) {
                //  ignore
              } else {
                const c2 = {
                  connection: {
                    ...this.project.envs[e].db[0].connection,
                    database: undefined
                  },
                  client: this.project.envs[e].db[0].client
                }

                this.handleSSL(c2)

                const result = await this.sqlMgr.testConnection(c2)

                if (result.code === 0) {
                  this.project.envs[e][0].ui.setup = 1
                } else {
                  this.project.envs[e][0].ui.setup = -1
                  passed = false
                  break
                }
              }
            }

            if (passed) {
              this.panel = null
            } else {
              // Connection was successful
              this.dialog.heading = this.$t('msg.info.dbConnected')
              this.dialog.type = 'success'
              this.dialog.show = true
            }
          } else {
            db.ui.setup = -1
            // Connection Failure:
            this.dialog.heading =
              this.$t('msg.error.dbConnectionFailed') + result.message
            this.dialog.type = 'error'
            this.dialog.show = true
          }
        }

        return true
      } else {
        return false
      }
    },

    sendAdvancedConfig(connection) {
      if (!connection.ssl) {
        return false
      }
      let sendAdvancedConfig = false
      const sslOptions = Object.values(connection.ssl).filter(el => !!el)
      if (sslOptions[0]) {
        sendAdvancedConfig = true
      } else {
      }
      return sendAdvancedConfig
    },

    handleSSL(db, creating = true) {
      const sendAdvancedConfig = this.sendAdvancedConfig(db.connection)
      if (!sendAdvancedConfig) {
        db.connection.ssl = undefined
      }

      if (db.connection.ssl) {
      }
    },
    getDatabaseForTestConnection(dbType) {
    },
    async testConnection(db, env, panelIndex) {
      this.$e('a:project:create:extdb:test-connection')
      this.$store.commit('notification/MutToggleProgressBar', true)
      try {
        if (!(await this.newTestConnection(db, env, panelIndex))) {
          this.handleSSL(db)

          if (db.client === 'sqlite3') {
            db.ui.setup = 1
          } else {
            const c1 = {
              connection: {
                ...db.connection,
                ...(db.client !== 'pg'
                  ? { database: this.testDatabaseNames[db.client] }
                  : {})
              },
              client: db.client
            }

            const result = await this.$api.utils.testConnection(c1)

            if (result.code === 0) {
              db.ui.setup = 1
              // this.dialog.heading = "Connection was successful"
              // this.dialog.type = 'success';
              // this.dialog.show = true;
              this.testSuccess = true
            } else {
              db.ui.setup = -1
              // this.activeDbNode.testConnectionStatus = false;
              this.dialog.heading =
                this.$t('msg.error.dbConnectionFailed') + result.message
              this.dialog.type = 'error'
              this.dialog.show = true
            }
          }
        }
      } catch (e) {
        console.log(e)
      } finally {
        this.$store.commit('notification/MutToggleProgressBar', false)
      }
    },
    getEnvironmentStatusAggregated(dbs) {
      return dbs.every(db => db.ui.setup === 1)
    },

    getEnvironmentStatusAggregatedNew(dbs) {
      return dbs.db.every(db => db.ui.setup === 1)
    },
    openFirstPanel() {
      if (!this.edit) {
        this.panel = 0
      }
    },
    onDatabaseTypeChanged(client, db1, index, env) {
      if (this.databaseNames[client] === 'mssql') {
        this.schema = 'dbo'
      } else if (this.databaseNames[client] === 'pg') {
        this.schema = 'public'
      }

      for (const env in this.project.envs) {
        if (this.project.envs[env].db.length > index) {
          const db = this.project.envs[env].db[index]
          Vue.set(db, 'client', this.databaseNames[client])

          if (client !== 'Sqlite') {
            const { ssl, ...connectionDet } = this.sampleConnectionData[client]

            Vue.set(db, 'connection', {
              ...connectionDet,
              database: `${this.project.title}_${env}_${index + 1}`,
              ssl: { ...ssl }
            })

            for (const env in this.project.envs) {
              if (this.project.envs[env].length > index) {
                this.setDBStatus(this.project.envs[env][index], 0)
              }
            }
          } else {
            db.connection = {}
            Vue.set(db, 'connection', {
              client: 'sqlite3',
              // connection: {filename: path.join(this.project.folder, `${this.project.title}_${env}_${index + 1}`)},
              connection: {
                filename: [
                  this.project.folder,
                  `${this.project.title}_${env}_${index + 1}`
                ].join('/')
              },
              database: [
                this.project.folder,
                `${this.project.title}_${env}_${index + 1}`
              ].join('/'),
              useNullAsDefault: true
            })
          }
        }
      }
    },
    selectDatabaseClient(database, index = 0) {
      if (this.client) {
        this.client[index] = database
      }
    },
    setDBStatus(db, status) {
      db.ui.setup = status
    },
    removeDBFromEnv(db, env, panelIndex, dbIndex) {
      for (const env in this.project.envs) {
        if (this.project.envs[env].db.length > dbIndex) {
          this.project.envs[env].db.splice(dbIndex, 1)
        }
      }
    },
    removeEnv(envKey) {
      delete this.project.envs[envKey]
      Vue.set(this.project, 'envs', { ...this.project.envs })
    }
  },
  fetch({ store, params }) {
  },
  beforeCreated() {
  },
  watch: {
    'project.title'(newValue, oldValue) {
      if (!newValue) {
        return
      }
      if (!this.edit) {
        // Vue.set(this.project, 'folder', slash(path.join(this.baseFolder, newValue)))
        Vue.set(this.project, 'folder', [this.baseFolder, newValue].join('/'))
        // }//this.project.folder = `${this.baseFolder}/${newValue}`;

        for (const env in this.project.envs) {
          for (const [index, db] of this.project.envs[env].db.entries()) {
            // db.connection.database = `${this.project.title}_${env}_${index}`
            if (db.client !== 'sqlite3') {
              Vue.set(
                db.connection,
                'database',
                `${this.project.title}_${env}_${index + 1}`
              )
            } else {
              Vue.set(
                db.connection,
                'database',
                `${this.project.title}_${env}_${index + 1}`
              )
            }
          }
        }
      }
    },
    'project.envs': {
      deep: true,
      handler(envs) {
        if (typeof envs === 'object' && envs) {
          Object.entries(envs).forEach(([key, env]) => {
            let res = 1
            const msg = {}
            for (const db of env.db) {
              res = db.ui.setup < res ? db.ui.setup : res
            }
            if (this.edit) {
              Vue.set(this.project.ui, key, '')
            } else {
              switch (res) {
                case -1:
                  msg.color = 'red'
                  // msg.msg = ' ( Invalid database parameters )'
                  msg.msg = `( ${this.$t('msg.error.dbConnectionStatus')} )`
                  break
                case 0:
                  msg.color = 'warning'
                  msg.msg = ' ( Click to validate database credentials )'
                  break
                case 1:
                  msg.color = 'green'
                  // msg.msg = ' ( Environment Validated )'
                  msg.msg = `( ${this.$t('msg.info.dbConnectionStatus')} )`
                  break
              }
              Vue.set(this.project.ui, key, msg)
            }
          })
        }
      }
    }
  },
  async created() {
    this.compErrorMessage =
      this.compErrorMessages[
        Math.floor(Math.random() * this.compErrorMessages.length)
      ]

    if (this.edit) {
      try {
        let data = await this.$store.dispatch('sqlMgr/ActSqlOp', [
          null,
          'xcProjectGetConfig'
        ])
        data = JSON.parse(data.config)
        this.constructProjectJsonFromProject(data)
        this.$set(this.project, 'folder', data.folder)
      } catch (e) {
        this.$toast.error(e.message).goAway(3000)
      }
    } else {
      this.project = JSON.parse(JSON.stringify(this.defaultProject))
      // this.edit = false;

      /**
       *  Figure out which databases users has by scanning port numbers
       *      preference can be - pg | mysql | mssql | oracledb | sqlite
       *      create this.project based on the database
       *
       *
       */
      let dbsAvailable = [] // await PortScanner.getOpenDbPortsAsList();
      // // setting MySQL as default value if no databases are available
      // if (!dbsAvailable || !dbsAvailable.length) {
      dbsAvailable = ['MySQL']
      // }

      this.selectDatabaseClient(dbsAvailable[0], 0)

      // iterating over environment and setting default connection details based
      // on first available database
      for (const env in this.project.envs) {
        for (const db of this.project.envs[env].db) {
          db.client = this.databaseNames[dbsAvailable[0]]

          if (db.client === 'sqlite3') {
            db.connection = {
              ...this.sampleConnectionData[dbsAvailable[0]]
            }

            db.ui.setup = 0
          } else {
            db.connection = {
              ...this.sampleConnectionData[dbsAvailable[0]],
              ssl: { ...this.sampleConnectionData[dbsAvailable[0]].ssl }
            }
          }
        }
      }
    }
  },
  beforeMount() {
  },
  mounted() {
    this.$set(
      this.project,
      'title',
      uniqueNamesGenerator({
        dictionaries: [[starWars], [adjectives, animals]][
          Math.floor(Math.random() * 2)
        ]
      })
        .toLowerCase()
        .replace(/[ -]/g, '_')
    )

    this.$nextTick(() => {
      const input = this.$refs.name.$el.querySelector('input')
      input.setSelectionRange(0, this.project.title.length)
      input.focus()
    })
  },
  beforeDestroy() {
  },
  destroy() {
  },
  validate({ params }) {
    return true
  },
  head() {
    return {
      title: this.$t('title.headCreateProject')
    }
  },
  props: {
    edit: {
      type: Boolean,
      default: false
    }
  },
  directives: {}
}
</script>

<style scoped>
.floating-button {
  position: fixed;
  right: 7%;
  bottom: 100px;
}

/deep/ .v-expansion-panel-header {
  padding: 0 6px;
  min-height: 50px !important;
}

/deep/ .monaco-overlay {
  align-items: stretch;
}

/deep/ .monaco-overlay .v-overlay__content {
  flex-grow: 1;
}

.monaco-overlay-close {
  position: absolute;
  right: 10px;
  top: 10px;
  z-index: 999;
  cursor: pointer !important;
}
</style>
<!--
/**
 * @copyright Copyright (c) 2021, Xgene Cloud Ltd
 *
 * @author Naveen MR <oof1lab@gmail.com>
 * @author Pranav C Balan <pranavxc@gmail.com>
 * @author Wing-Kam Wong <wingkwong.code@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/>.
 *
 */
-->
