<template>
  <q-dialog v-model="localOpen" :persistent="saving">
    <q-card class="full-width no-shadow" style="max-width: 800px">
      <q-form ref="correctionsForm" @submit="handleSave">
        <q-card-section>
          <div class="text-h6">
            {{ $t('registries.mappingLabel') }}
          </div>
        </q-card-section>

        <q-card-section>
          <table class="q-table--horizontal-separator q-table">
            <thead>
              <tr>
                <th class="text-left" width="30px" />

                <th class="text-left">
                  {{ $t('registries.table.head.name') }}
                </th>

                <template v-if="localEdit">
                  <th class="text-left">
                    {{ $t('registries.table.head.key') }}
                  </th>

                  <th class="text-left" />
                </template>
              </tr>
            </thead>

            <tbody>
              <tr class="q-tr" v-for="item in items" :key="item.id">
                <td class="q-td">
                  <q-checkbox v-model="item.selected" />
                </td>

                <td class="q-td">
                  <q-input v-if="localEdit" v-model="item.label" filled />
                  <template v-else>{{ item.label }}</template>
                </td>

                <template v-if="localEdit">
                  <td class="q-td">
                    <q-input v-model="item.name" filled />
                  </td>

                  <td class="q-td text-right">
                    <q-btn
                      type="button"
                      color="red"
                      :label="$t('registries.objectCard.delete')"
                      @click="removeItem(item.id)"
                    />
                  </td>
                </template>
              </tr>
            </tbody>
          </table>
        </q-card-section>

        <q-card-actions align="right">
          <q-btn
            type="button"
            color="primary"
            :label="$t('registries.objectCard.cancel')"
            @click="handleClose"
          />

          <q-btn
            v-if="localEdit"
            type="button"
            icon="add"
            color="primary"
            :label="$t('registries.table.addRow')"
            @click="pushItem"
          />

          <q-btn
            type="submit"
            icon="create"
            :loading="saving"
            :label="$t('registries.objectCard.save')"
            color="primary"
          >
            <template #loading>
              <q-spinner-gears />
            </template>
          </q-btn>
        </q-card-actions>
      </q-form>
    </q-card>
  </q-dialog>
</template>

<script lang="ts">
import { Component, PropSync, Prop, Vue } from 'vue-property-decorator';
import { v4 as getUUID } from 'uuid';
import cloneDeep from 'lodash/cloneDeep';
import { notifyError, notifySuccess } from '@utils/notify';

import {
  Registry,
  RegistryApi,
  RegistryTable,
  RegistryTableApi,
  ModifyResponse,
} from '@openapi/registry-service';
import { RegistryTableColumn } from '@/models/RegistryTableColumn';

const registryTableApi = new RegistryTableApi();
const registryApi = new RegistryApi();

@Component
export default class MappingTableDialog extends Vue {
  @PropSync('open', { default: false }) localOpen: boolean;
  @PropSync('edit', { default: false }) localEdit: boolean;
  @Prop({ required: true }) defaultValues: RegistryTableColumn[];
  @Prop() registryTable!: RegistryTable;
  @Prop() registry!: Registry;

  saving = false;

  items: RegistryTableColumn[] = [];
  schema: RegistryTable;

  mounted(): void {
    this.items = cloneDeep(this.defaultValues);
    this.schema = cloneDeep(this.registryTable)
  }

  pushItem(): void {
    this.items.push({
      id: getUUID(),
      label: '',
      name: '',
      selected: false,
    });
  }

  removeItem(id: string): void {
    this.items = this.items.filter((item) => item.id !== id);
  }

  handleSave(): void {
    this.items = this.items.filter((item) => item.label && item.name);

    this.$q
      .dialog({
        title: this.$t('registries.objectCard.save') as string,
        message: this.$t('registries.objectCard.saveInfo') as string,
        cancel: true,
      })
      .onOk(() => {
        if (this.localEdit) {
          this.saving = true;

          this.saveSchema().then(() => {
            notifySuccess(this.$t('registries.schemaSavedSuccessfully') as string, '');
            this.handleClose();
          }).finally(() => {
            this.saving = false;
          }).catch((e: Error) => {
            notifyError(e.message.toString());
          });
        } else {
          this.handleClose();
        }
      });
  }

  handleClose(): void {
    this.localOpen = false;
    this.$emit('update', cloneDeep(this.items))
  }

  async saveSchema(): Promise<ModifyResponse> {
    const { id } = this.schema || {};
    const context: RegistryTable = {
      ...this.schema,
      attrList: this.items,
    };

    if (id) {
      const { data: responce } = await registryTableApi.updateRegistryTable([context])
      return responce;
    }

    const { data } = await registryTableApi.createRegistryTable([context])
    const { modified, objectIds } = data;

    this.schema = {
      modified,
      name: 'RegistryTable',
      id: objectIds ? objectIds[0] : '',
    };

    const contextRegistry: Registry = {
      ...this.registry,
      // @ts-ignore TODO Добавить в интерфейс
      registryTable: this.schema.id,
    };
    const { data: responce } = await registryApi.updateRegistry([contextRegistry]);
    return responce;
  }
}
</script>
