<template>
  <v-card class="pb-2">

    <v-toolbar flat height="42" class="toolbar-border-bottom">
      <v-spacer></v-spacer>
      <x-btn outlined tooltip="Validation Documentation"
             color="primary"
             small
             href="https://docs.nocodb.com/en/v0.5/database/database-model-validation" target="_blank">
        <v-icon small left>mdi-book-open-variant</v-icon>
        Validation Docs
      </x-btn>
      <x-btn outlined tooltip="Reload validation"
             color="primary"
             small
             @click="loadTableModelMeta">
        <v-icon small left>refresh</v-icon>
        Reload
      </x-btn>
      <x-btn outlined tooltip="Save Changes"
             color="primary"
             small
             :disabled="!edited || loading"
             @click.prevent="saveValidations">
        <v-icon small left>save</v-icon>
        Save
      </x-btn>
    </v-toolbar>
    <template v-if="columns">


      <p class="title mt-6 mb-6"> Table : <span class="text-capitalize">{{ columns._tn }}</span><br>
        <span class="font-weight-thin">Write Validations For Columns</span></p>

      <!--      <v-row justify="center">
              <v-col cols="4" class="d-flex align-center">
                <label class="mr-3">Table Alias</label>
                <v-text-field @input="edited = true" v-model="columns._tn">

                </v-text-field>
              </v-col>
            </v-row>-->


      <v-simple-table style="max-width:800px; margin:0 auto" class="mb-10" dense v-slot:default>
        <thead>
        <tr>
          <th>Column Name</th>
          <th>Alias</th>
          <th>Validators</th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="(item,i) in columns.columns">
          <td>{{ item.cn }}</td>
          <td>
            <v-edit-dialog lazy>
              <span> {{ item._cn }}</span>
              <template v-slot:input>
                <v-text-field
                  @input="edited=true"
                  v-model="item._cn"
                  label="Edit"
                  single-line
                ></v-text-field>
              </template>
            </v-edit-dialog>
          </td>
          <td>
            <x-btn
              @click="editOrAddValidation(item)"
              :tooltip="`Edit/Add validation for '${item.cn}' column`" color="primary"
              style="text-transform:capitalize" x-small outlined>
              <v-icon class=" mr-1" x-small>mdi-lead-pencil</v-icon>
              Validation ({{ item.validate.func.length }})
            </x-btn>
          </td>
        </tr>
        </tbody>
      </v-simple-table>


      <!--      <v-expansion-panels accordion style="width: 70%; min-width: 500px; margin:5px auto">-->
      <!--        <v-expansion-panel-->
      <!--          v-for="(item,i) in columns.columns"-->
      <!--          :key="i"-->
      <!--        >-->
      <!--          <v-expansion-panel-header>{{ item.cn }} <span-->
      <!--            class="caption grey&#45;&#45;text ml-2">({{ item.validate.func.length }} validations)</span>-->
      <!--          </v-expansion-panel-header>-->
      <!--          <v-expansion-panel-content>-->

      <!--            <v-toolbar class="elevation-0" flat height="42">-->
      <!--              <v-spacer>-->
      <!--              </v-spacer>-->

      <!--              <x-btn outlined tooltip="Add new validation"-->
      <!--                     color="primary"-->
      <!--                     small-->
      <!--                     @click.prevent="(item.validate.func.push(''),edited=true,scrollAndFocusLastRow())">-->
      <!--                <v-icon small left>mdi-plus</v-icon>-->
      <!--                Add Validation-->
      <!--              </x-btn>-->
      <!--            </v-toolbar>-->

      <!--            <v-simple-table v-if="item.validate.func && item.validate.func.length" dense>-->
      <!--              <thead>-->
      <!--              <tr>-->
      <!--                <th class="caption font-weight-normal">Validation Function</th>-->
      <!--                <th class="caption font-weight-normal">Error Message</th>-->
      <!--                &lt;!&ndash;                <th class="caption font-weight-normal">Optional Argument</th>&ndash;&gt;-->
      <!--                <th></th>-->
      <!--              </tr>-->
      <!--              </thead>-->
      <!--              <tbody>-->
      <!--              <tr v-for="(func,i) in item.validate.func">-->
      <!--                <td>-->
      <!--                  <v-edit-dialog-->
      <!--                    lazy-->
      <!--                  >-->
      <!--                    <span>{{ func }}</span>-->
      <!--                    <template v-slot:input>-->

      <!--                      <v-autocomplete-->
      <!--                        @change="onFunctionChange(i,item)"-->
      <!--                        dense-->
      <!--                        v-model="item.validate.func[i]"-->
      <!--                        :items="fnList"-->
      <!--                        item-text="func"-->
      <!--                      ></v-autocomplete>-->
      <!--                    </template>-->
      <!--                  </v-edit-dialog>-->
      <!--                </td>-->
      <!--                <td>-->
      <!--                  <v-edit-dialog lazy>-->
      <!--                    <span> {{ item.validate.msg[i] }}</span>-->
      <!--                    <template v-slot:input>-->
      <!--                      <v-text-field-->
      <!--                        @input="edited=true"-->
      <!--                        v-model="item.validate.msg[i]"-->
      <!--                        label="Edit"-->
      <!--                        single-line-->
      <!--                      ></v-text-field>-->
      <!--                    </template>-->
      <!--                  </v-edit-dialog>-->
      <!--                </td>-->
      <!--                &lt;!&ndash;                <td>&ndash;&gt;-->
      <!--                &lt;!&ndash;                  <v-edit-dialog lazy>&ndash;&gt;-->
      <!--                &lt;!&ndash;                    <span> {{ item.validate.args[i] }}</span>&ndash;&gt;-->
      <!--                &lt;!&ndash;                    <template v-slot:input>&ndash;&gt;-->
      <!--                &lt;!&ndash;                      <v-text-field&ndash;&gt;-->
      <!--                &lt;!&ndash;                        @input="edited=true"&ndash;&gt;-->
      <!--                &lt;!&ndash;                        v-model="item.validate.args[i]"&ndash;&gt;-->
      <!--                &lt;!&ndash;                        label="Edit"&ndash;&gt;-->
      <!--                &lt;!&ndash;                        single-line&ndash;&gt;-->
      <!--                &lt;!&ndash;                      ></v-text-field>&ndash;&gt;-->
      <!--                &lt;!&ndash;                    </template>&ndash;&gt;-->
      <!--                &lt;!&ndash;                  </v-edit-dialog>&ndash;&gt;-->
      <!--                &lt;!&ndash;                </td>&ndash;&gt;-->


      <!--                <td>-->
      <!--                  <x-icon-->
      <!--                    small-->
      <!--                    color="error" tooltip="Delete role" @click="deleteValidation(item,i)">-->
      <!--                    mdi-delete-forever-->
      <!--                  </x-icon>-->
      <!--                </td>-->
      <!--              </tr>-->
      <!--              </tbody>-->
      <!--            </v-simple-table>-->
      <!--            <div v-else class="d-flex justify-center">-->
      <!--              <v-alert dense outlined type="info" color="grey lighten-1" icon="mdi-information-outline" class="caption"-->
      <!--                       style="width:auto">-->
      <!--                No validation for '{{ item.cn }}'-->
      <!--              </v-alert>-->
      <!--            </div>-->
      <!--          </v-expansion-panel-content>-->
      <!--        </v-expansion-panel>-->
      <!--      </v-expansion-panels>-->
    </template>


    <v-dialog v-model="validatorEditDialog" max-width="700px">

      <v-card v-if="clickedItem">
        <v-card-title class="headline justify-center mb-5">Validations for '{{ clickedItem.cn }}({{ clickedItem.dt }})'
        </v-card-title>
        <v-card-text>

          <div class="d-flex">
            <v-spacer>
            </v-spacer>

            <v-btn outlined x-small @click="validatorEditDialog = false">Cancel</v-btn>
            <x-btn outlined tooltip="Add new validation"
                   color="primary"
                   x-small
                   @click.prevent="(clickedItem.validate.func.push(''),edited=true,scrollAndFocusLastRowInModal())">
              <v-icon small left>mdi-plus</v-icon>
              Add Validation
            </x-btn>
            <v-btn outlined color="primary" x-small @click.prevent="saveValidationForColumn(clickedItem)">Save</v-btn>
          </div>
          <v-simple-table v-if="clickedItem.validate.func && clickedItem.validate.func.length" dense>
            <thead>
            <tr>
              <th class="caption font-weight-normal">Validation Function</th>
              <th class="caption font-weight-normal">Error Message</th>
              <!--                <th class="caption font-weight-normal">Optional Argument</th>-->
              <th></th>
            </tr>
            </thead>
            <tbody>
            <tr v-for="(func,i) in clickedItem.validate.func">
              <td>
                <v-edit-dialog
                  lazy
                >
                  <span>{{ func }}</span>
                  <template v-slot:input>

                    <v-autocomplete
                      @change="onFunctionChange(i,clickedItem)"
                      dense
                      v-model="clickedItem.validate.func[i]"
                      :items="fnList"
                      item-text="func"
                    ></v-autocomplete>
                  </template>
                </v-edit-dialog>
              </td>
              <td>
                <v-edit-dialog lazy>
                  <span> {{ clickedItem.validate.msg[i] }}</span>
                  <template v-slot:input>
                    <v-text-field
                      @input="edited=true"
                      v-model="clickedItem.validate.msg[i]"
                      label="Edit"
                      single-line
                    ></v-text-field>
                  </template>
                </v-edit-dialog>
              </td>
              <!--                <td>-->
              <!--                  <v-edit-dialog lazy>-->
              <!--                    <span> {{ clickedItem.validate.args[i] }}</span>-->
              <!--                    <template v-slot:input>-->
              <!--                      <v-text-field-->
              <!--                        @input="edited=true"-->
              <!--                        v-model="clickedItem.validate.args[i]"-->
              <!--                        label="Edit"-->
              <!--                        single-line-->
              <!--                      ></v-text-field>-->
              <!--                    </template>-->
              <!--                  </v-edit-dialog>-->
              <!--                </td>-->


              <td>
                <x-icon
                  small
                  color="error" tooltip="Delete role" @click="deleteValidation(clickedItem,i)">
                  mdi-delete-forever
                </x-icon>
              </td>
            </tr>
            </tbody>
          </v-simple-table>
          <div v-else class="d-flex justify-center">
            <v-alert dense outlined type="info" color="grey lighten-1" icon="mdi-information-outline"
                     class="caption mt-4"
                     style="width:auto">
              No validation for '{{ clickedItem.cn }}'
            </v-alert>
          </div>
        </v-card-text>
        <!--        <v-card-actions>-->
        <!--          <v-spacer></v-spacer>-->
        <!--    -->
        <!--        </v-card-actions>-->
      </v-card>
    </v-dialog>


  </v-card>
</template>

<script>

import {SqlUI} from "@/helpers/SqlUiFactory";

const validatorFnList = [{"func": "contains", "args": '', msg: 'Error contains'}, {
  "func": "equals",
  "args": '',
  msg: 'Error equals'
}, {
  "func": "isAfter",
  "args": '',
  msg: 'Error isAfter'
}, {"func": "isAlpha", "args": '', msg: 'Error isAlpha'}, {
  "func": "isAlphanumeric",
  "args": '',
  msg: 'Error isAlphanumeric'
}, {
  "func": "isAscii",
  "args": '',
  msg: 'Error isAscii'
}, {"func": "isBase32", "args": '', msg: 'Error isBase32'}, {"func": "isBase64", "args": '', msg: 'Error isBase64'}, {
  "func": "isBefore",
  "args": '',
  msg: 'Error isBefore'
}, {"func": "isBIC", "args": '', msg: 'Error isBIC'}, {"func": "isBoolean", "args": '', msg: 'Error isBoolean'}, {
  "func": "isBtcAddress",
  "args": '',
  msg: 'Error isBtcAddress'
}, {"func": "isByteLength", "args": '', msg: 'Error isByteLength'}, {
  "func": "isCreditCard",
  "args": '',
  msg: 'Error isCreditCard'
}, {
  "func": "isCurrency",
  "args": '',
  msg: 'Error isCurrency'
}, {"func": "isDataURI", "args": '', msg: 'Error isDataURI'}, {"func": "isDate", "args": '', msg: 'Error isDate'}, {
  "func": "isDecimal",
  "args": '',
  msg: 'Error isDecimal'
}, {"func": "isDivisibleBy", "args": '', msg: 'Error isDivisibleBy'}, {
  "func": "isEAN",
  "args": '',
  msg: 'Error isEAN'
}, {
  "func": "isEmail",
  "args": '',
  msg: 'Error isEmail'
}, {"func": "isEmpty", "args": '', msg: 'Error isEmpty'}, {
  "func": "isEthereumAddress",
  "args": '',
  msg: 'Error isEthereumAddress'
}, {
  "func": "isFloat",
  "args": '',
  msg: 'Error isFloat'
}, {"func": "isFQDN", "args": '', msg: 'Error isFQDN'}, {"func": "isFullWidth", "args": '', msg: 'Error isFullWidth'}, {
  "func": "isHalfWidth",
  "args": '',
  msg: 'Error isHalfWidth'
}, {"func": "isHash", "args": '', msg: 'Error isHash'}, {
  "func": "isHexadecimal",
  "args": '',
  msg: 'Error isHexadecimal'
}, {
  "func": "isHexColor",
  "args": '',
  msg: 'Error isHexColor'
}, {"func": "isHSL", "args": '', msg: 'Error isHSL'}, {"func": "isIBAN", "args": '', msg: 'Error isIBAN'}, {
  "func": "isIdentityCard",
  "args": '',
  msg: 'Error isIdentityCard'
}, {"func": "isIMEI", "args": '', msg: 'Error isIMEI'}, {
  "func": "isIn",
  "args": '',
  msg: 'Error isIn'
}, {"func": "isInt", "args": '', msg: 'Error isInt'}, {
  "func": "isIP",
  "args": '',
  msg: 'Error isIP'
}, {"func": "isIPRange", "args": '', msg: 'Error isIPRange'}, {"func": "isISBN", "args": '', msg: 'Error isISBN'}, {
  "func": "isISIN",
  "args": '',
  msg: 'Error isISIN'
}, {"func": "isISO8601", "args": '', msg: 'Error isISO8601'}, {
  "func": "isISO31661Alpha2",
  "args": '',
  msg: 'Error isISO31661Alpha2'
}, {
  "func": "isISO31661Alpha3",
  "args": '',
  msg: 'Error isISO31661Alpha3'
}, {"func": "isISRC", "args": '', msg: 'Error isISRC'}, {
  "func": "isISSN",
  "args": '',
  msg: 'Error isISSN'
}, {"func": "isJSON", "args": '', msg: 'Error isJSON'}, {
  "func": "isJWT",
  "args": '',
  msg: 'Error isJWT'
}, {"func": "isLatLong", "args": '', msg: 'Error isLatLong'}, {"func": "isLength", "args": '', msg: 'Error isLength'}, {
  "func": "isLocale",
  "args": '',
  msg: 'Error isLocale'
}, {"func": "isLowercase", "args": '', msg: 'Error isLowercase'}, {
  "func": "isMACAddress",
  "args": '',
  msg: 'Error isMACAddress'
}, {
  "func": "isMagnetURI",
  "args": '',
  msg: 'Error isMagnetURI'
}, {"func": "isMD5", "args": '', msg: 'Error isMD5'}, {"func": "isMimeType", "args": '', msg: 'Error isMimeType'}, {
  "func": "isMobilePhone",
  "args": '',
  msg: 'Error isMobilePhone'
}, {"func": "isMongoId", "args": '', msg: 'Error isMongoId'}, {
  "func": "isMultibyte",
  "args": '',
  msg: 'Error isMultibyte'
}, {
  "func": "isNumeric",
  "args": '',
  msg: 'Error isNumeric'
}, {"func": "isOctal", "args": '', msg: 'Error isOctal'}, {
  "func": "isPassportNumber",
  "args": '',
  msg: 'Error isPassportNumber'
}, {
  "func": "isPort",
  "args": '',
  msg: 'Error isPort'
}, {"func": "isPostalCode", "args": '', msg: 'Error isPostalCode'}, {
  "func": "isRFC3339",
  "args": '',
  msg: 'Error isRFC3339'
}, {
  "func": "isRgbColor",
  "args": '',
  msg: 'Error isRgbColor'
}, {"func": "isSemVer", "args": '', msg: 'Error isSemVer'}, {
  "func": "isSurrogatePair",
  "args": '',
  msg: 'Error isSurrogatePair'
}, {
  "func": "isUppercase",
  "args": '',
  msg: 'Error isUppercase'
}, {"func": "isSlug", "args": '', msg: 'Error isSlug'}, {
  "func": "isTaxID",
  "args": '',
  msg: 'Error isTaxID'
}, {"func": "isURL", "args": '', msg: 'Error isURL'}, {
  "func": "isUUID",
  "args": '',
  msg: 'Error isUUID'
}, {"func": "isVariableWidth", "args": '', msg: 'Error isVariableWidth'}, {
  "func": "isWhitelisted",
  "args": '',
  msg: 'Error isWhitelisted'
}, {"func": "matches", "args": '', msg: 'Error matches'}];

export default {
  name: "validation",
  props: ['nodes'],
  data: () => ({
    fnList: validatorFnList,
    columns: null,
    validators: [{}, {}],
    tableMeta: null,
    edited: false,
    loading: false,
    clickedItem: null,
    validatorEditDialog: false
  }),
  methods: {

    editOrAddValidation(item) {
      this.clickedItem = JSON.parse(JSON.stringify(item));
      this.validatorEditDialog = true;
    },


    // async loadColumnList() {
    //   const result = await this.$store.dispatch('sqlMgr/ActSqlOp', [{
    //     env: this.nodes.env,
    //     dbAlias: this.nodes.dbAlias
    //   }, 'columnList', {
    //     tn: this.nodes.tn
    //   }]);
    //   console.log("table ", result.data.list);
    //   this.columns = result.data.list;
    // },
    async loadTableModelMeta() {
      this.edited = false;
      this.tableMeta = await this.$store.dispatch('sqlMgr/ActSqlOp', [{
        env: this.nodes.env,
        dbAlias: this.nodes.dbAlias
      }, 'tableXcModelGet', {
        tn: this.nodes.tn
      }]);
      this.columns = JSON.parse(this.tableMeta.meta)
    },

    scrollAndFocusLastRow() {
      this.$nextTick(() => {
        const menuActivator = this.$el && this.$el.querySelector('.v-expansion-panel--active table tr:last-child .v-small-dialog__activator__content');
        if (menuActivator) {
          menuActivator.click();
          this.$nextTick(() => {
            const inputField = document.querySelector('.menuable__content__active input');
            inputField && inputField.select()
          })
        }
      })
    },
    scrollAndFocusLastRowInModal() {
      this.$nextTick(() => {
        const modal = document.querySelector('.v-dialog--active');
        modal.scrollTop = 99999;
        const menuActivator = modal.querySelector('table tr:last-child .v-small-dialog__activator__content');
        if (menuActivator) {
          menuActivator.click();
          this.$nextTick(() => {
            const inputField = document.querySelector('.menuable__content__active input');
            inputField && inputField.select()
          })
        }
      })
    },
    async saveValidations() {
      this.edited = false;
      try {
        await this.$store.dispatch('sqlMgr/ActSqlOp', [{
          env: this.nodes.env,
          dbAlias: this.nodes.dbAlias
        }, 'xcModelSet', {
          tn: this.nodes.tn,
          meta: this.columns
        }]);
        this.$toast.success('Successfully updated validations').goAway(3000);
      } catch (e) {
        this.$toast.error('Failed to update validations').goAway(3000);
      }
    },
    async saveValidationForColumn(clickedItem) {

      if (clickedItem) {
        const item = this.columns.columns.find(it => it.cn === clickedItem.cn);
        if (item) {
          Object.assign(item, clickedItem);
          await this.saveValidations();
          this.validatorEditDialog = false;
          this.clickedItem = null;
        }
      }
    },
    onFunctionChange(i, item) {
      this.edited = true;
      const fn = validatorFnList.find(({func}) => func === item.validate.func[i]);
      item.validate.msg[i] = `Validation failed : ${item.validate.func[i]}(${this.nodes.tn}.${item.cn})`;
      item.validate.args[i] = fn.args;
    },
    deleteValidation(item, i) {
      this.edited = true;
      item.validate.func.splice(i, 1);
      item.validate.args.splice(i, 1);
      item.validate.msg.splice(i, 1);
    }
  },
  async created() {
    try {
      // await this.loadColumnList();
      await this.loadTableModelMeta();
    } catch (e) {
      throw e;
    } finally {

    }

  }
}
</script>

<style scoped>

</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/>.
 *
 */
-->
