<template>
  <q-dialog v-model="open" @hide="clearModel" :persistent="saving">
    <q-card class="full-width no-shadow" style="max-width: 800px">
      <q-form class="full-width no-shadow q-py-md" @submit="submit()">
        <div class="text-h6 q-px-md">
          {{ $t('criteriaDirectory.downloadDialog') }}
        </div>
        <q-card-section class="q-gutter-y-md">
          <q-input
            filled
            :rules="[validateFileName]"
            :error-message="$t('processes.validationErrors.errorProcessId')"
            v-model="dialogData.name"
            label="Наименование"
          />
          <div class="flex justify-between items-start no-wrap">
            <q-file
              accept=".bpmn"
              clearable
              filled
              counter
              label="Загрузить файл"
              ref="processDialogFile"
              v-model="upload.file"
              :rules="[validateFileName]"
              @input="fileHandler"
              :error-message="
                upload.file
                  ? $t('processes.validationErrors.errorFileName')
                  : $t('processes.validationErrors.errorFileRequired')
              "
            />
            <q-btn
              color="primary"
              class="q-ml-sm flex-item-button"
              filled
              label="Импорт"
              @click="isBpmnCloudLoader = true"
            />
            <BaseBpmnCloudLoader
              :show.sync="isBpmnCloudLoader"
              value-mode="file"
              @getBpmn="bpmnSchemaUploadHandler"
            />
          </div>
        </q-card-section>
        <q-card-actions align="right">
          <q-btn
            type="submit"
            :loading="saving"
            :label="$t('criteriaDirectory.download')"
            color="primary"
            @click="create"
          >
            <template #loading>
              <q-spinner-gears />
            </template>
          </q-btn>
          <q-btn
            color="white"
            text-color="primary"
            :loading="saving"
            :label="$t('criteriaDirectory.cancel')"
            @click="cancelSave()" 
          >
            <template #loading>
              <q-spinner-gears />
            </template>
          </q-btn>
        </q-card-actions>
      </q-form>
    </q-card>
  </q-dialog>
</template>

<script lang="ts">
import { Component, PropSync, Vue } from 'vue-property-decorator';
import { ValidatorResponse } from '@interfaces/base/ValidatorRespose';
import { fileNameValidator } from '@/utils/field-validation/fileName';
import { multipleUseValidator } from '@/utils/field-validation/multipleUse';
import { QSelectOption } from '@models/models-ui';
import { ImporterApiHelper } from '@services/importer-service';
import BaseBpmnCloudLoader from '@components/common/base-bpmn-cloud-loader/index.vue';
import {
  createDocument,
  updateAttachment,
  updateDocument,
} from '@services/registry-service';
import get from 'lodash/get';
import { DocumentApi } from '@openapi/registry-service';
const documentApi = new DocumentApi();

@Component({
  components: {
    BaseBpmnCloudLoader,
  },
})

export default class DownloadDialog extends Vue {
  @PropSync('openFormDialog') open: boolean;
  saving = false;
  isBpmnCloudLoader=false;
  upload: any = {
    file: null,
    loading: false,
  }
  dialogData: any = {
    name:'',
    id: '',
    modified: '',
    attachment: false
  };

  bpmnSchemaUploadHandler(val:any): void {
    this.dialogData.name = val.code;
    this.upload.file = val.value;
  }

  async create() {
    const validation = await this.validate();

    if (!validation.isValid) {
      this.$q.notify({
        color: 'negative',
        icon: 'error',
        message: validation.message,
      });
      return;
    }

    try {
      this.saving = true;
      const doc = { id: '', name: this.dialogData.name }
      const { data: docResult } = await createDocument('Process', [ doc ]);

      this.dialogData.id = get(docResult, 'objectIds[0]');

      if (this.upload.file) {
        const file = new File(
          [this.upload.file],
          `${this.dialogData.name}.bpmn`
        );
        await updateAttachment(
          'Process',
          this.dialogData.id,
          undefined,
          [file]
        );
        await updateDocument('Process', [this.dialogData])
          .then(() => {
            this.$emit('createData', this.dialogData);
            this.$q.notify({
              color: 'positive',
              icon: 'check_circle_outline',
              message: 'Успешно',
            });
          })
      }
    } catch (e) {
      this.$q.notify({
        color: 'negative',
        icon: 'error',
        message: e.message,
      });
    } finally {
      this.saving = false;
      this.$emit('createData');
    }
  }

  async validate(): Promise<ValidatorResponse> {
    if (!this.dialogData.name) {
      return {
        isValid: false,
        message: 'Заполните все поля',
      };
    }
    if (!this.validateFileName(this.dialogData.name)) {
      return {
        isValid: false,
        message: 'File error',
      };
    }
    if (!this.upload?.file) {
      return {
        isValid: false,
        message: 'Необходимо загрузить файл процесса',
      };
    }
    if (!this.validateFileName(this.upload.file)) {
      return {
        isValid: false,
        message: 'File error',
      };
    }
    const fileNameValidation = await fileNameValidator(this.upload.file);
    
    if (!fileNameValidation.isValid) {
      return {
        isValid: false,
        message: 'Наименование файла не совпадает с id процесса', 
      };
    }
    const multipleUseValidation = await multipleUseValidator(
      this.upload.file,
      this.$route.params.id
    );
    if (!multipleUseValidation.isValid) {
      return {
        isValid: false,
        message: 'Процесс уже используется в базовой услуге',
      };
    }
    return {
        isValid: true,
        message: '',
    };
  }

  fileHandler(file: any) {
    if(file && file.name) {
      this.dialogData.name = file.name.replace('.bpmn', '')
    }
  }

  validateFileName(value: string | File): boolean {
    if (typeof value === 'string') {
      return value === value.match(/^[а-яёЁА-Я\w.]+$/)?.[0];
    } else if (value instanceof File) {
      return value.name === value.name.match(/^[а-яёЁА-Я\w.]+$/)?.[0];
    }
    return true;
  }

  cancelSave(): void {
    this.open = false;
    this.upload = {
      file: null,
      loading: false,
    }
    this.dialogData = {
      name:'',
      id: '',
      modified: '',
      attachment: false
    };
  }

  async created(): Promise<void> {
  }

  submit(): void {
  }

  clearModel(): void {
    this.open = false;
  }
}
</script>

<style scoped lang="scss">
  .flex-item-button {
    min-width: 90px;
    height: 56px;
  }
  </style>
