<i18n>
{
  "en": {
    "title": "Screen forms",
    "forms": {
      "type": "Type",
      "actions": "Actions",
      "tableTitle": "Screen forms",
      "id": "id",
      "noFormsResult": "No Forms result",
      "jsonEditor": "JSON editor",
      "JSONDialog": {
        "cancel": "Cancel",
        "create": "Create",
        "title": "Paste schema in code editor"
      },
      "errors": {
        "loadForms": "There was an error while loading view schemas, try refreshing",
        "loadFile": "There was an error while loading file, try again",
        "createSchema": "There was an error while creating the schema, try again",
        "deleteForm": "There was an error while deleting the schema, try again",
        "downloadForm": "There was an error while downloading the schema, try again",
        "schema": {
          "prefix": "The loaded schema has invalid list of ",
          "attrSuffix": "attributes",
          "groupSuffix": "groups"
        }
      },
      "table": {
        "reception": "Reception",
        "applicant": "Applicant",
        "statementForm": "Statement details",
        "interagencies": "Interdepartmental requests",
        "documents": {
          "mvz": "Documents added by a specialist",
          "applicant": "Applicant",
          "result": "Processes"
        },
        "form": "Schema",
        "formRequest": "Request schema",
        "formResponse": "Response schema",
        "btn": {
          "editForm": "Edit schema",
          "createForm": "Create empty schema",
          "createFormFromFile": "Create schema from file",
          "createFormFromJson": "Create schema from JSON",
          "downloadForm": "Download schema",
          "delete": "Delete",
          "addRow": "Add another form schema"
        },
        "customFormTooltip": "The custom form is used"
      }
    }
  },
  "ru": {
    "title": "Экранные формы",
    "forms": {
      "type": "Тип",
      "actions": "Действия",
      "tableTitle": "Формы заявлений",
      "id": "Идентификатор",
      "noFormsResult": "Нет результата",
      "jsonEditor": "Редактор JSON",
      "JSONDialog": {
        "cancel": "Отмена",
        "create": "Создать",
        "title": "Вставьте json формы"
      },
      "errors": {
        "loadForms": "Ошибка при загрузке экранных форм",
        "loadFile": "Произошла ошибка при загрузке файла, попробуйте снова",
        "createSchema": "Во время создания схемы произошла ошибка, попробуйте снова",
        "deleteForm": "Во время удаления схемы произошла ошибка, попробуйте снова",
        "downloadForm": "Во время скачивания схемы произошла ошибка, попробуйте снова",
        "schema": {
          "prefix": "В загруженной схеме неверно настроен список",
          "attrSuffix": "атрибутов",
          "groupSuffix": "групп"
        }
      },
      "table": {
        "reception": "Очный прием",
        "applicant": "Заявитель",
        "statementForm": "Данные заявления",
        "interagencies": "Межведомственные запросы",
        "documents": {
          "mvz": "Документы добавляемые специалистом",
          "applicant": "Входящие документы",
          "result": "Результирующие документы"
        },
        "form": "Экранная форма",
        "formRequest": "Экранная форма запроса",
        "formResponse": "Экранная форма ответа",
        "btn": {
          "editForm": "Редактировать форму",
          "createForm": "Создать пустую форму",
          "createFormFromFile": "Создать из файла",
          "createFormFromJson": "Создать из JSON",
          "downloadForm": "Скачать форму",
          "delete": "Удалить",
          "addRow": "Добавить еще одну схему формы"
        },
        "customFormTooltip": "Используется форма текущей услуги"
      }
    }
  }
}
</i18n>

<template>
  <div>
    <div
      v-if="form"
      :style="{ minWidth: '160px' }"
      class="flex full-width items-center"
    >
      <q-btn
        dense
        flat
        color="primary"
        icon="edit"
        class="q-mr-sm"
        @click="edit"
      >
        <q-tooltip :delay="500">
          {{ $t('forms.table.btn.editForm') }}
        </q-tooltip>
      </q-btn>
      <q-btn dense flat color="primary" icon="cloud_download" @click="download">
        <q-tooltip :delay="500">
          {{ $t('forms.table.btn.downloadForm') }}
        </q-tooltip>
      </q-btn>
      <q-icon
        v-if="form && form.parentServiceId"
        class="self-start"
        size="16px"
        name="settings"
        color="teal-8"
      >
        <q-tooltip :delay="500">
          {{ $t('forms.table.customFormTooltip') }}
        </q-tooltip>
      </q-icon>
      <q-btn
        dense
        flat
        color="negative"
        icon="delete"
        class="q-ml-auto"
        @click="deleteForm"
      >
        <q-tooltip :delay="500">
          {{ $t('forms.table.btn.delete') }}
        </q-tooltip>
      </q-btn>
    </div>
    <div v-else class="flex items-center full-width">
      <q-btn
        dense
        flat
        color="secondary"
        icon="add_box"
        class="q-mr-sm"
        @click="() => createForm(createEmptyForm())"
      >
        <q-tooltip :delay="500">
          {{ $t('forms.table.btn.createForm') }}
        </q-tooltip>
      </q-btn>
      <q-btn
        dense
        flat
        color="secondary"
        icon="note_add"
        class="q-mr-sm"
        @click="pickFile"
      >
        <q-tooltip :delay="500">
          {{ $t('forms.table.btn.createFormFromFile') }}
        </q-tooltip>
      </q-btn>
      <q-btn
        dense
        flat
        color="secondary"
        icon="content_paste"
        class="q-mr-sm"
        @click="launchJSONEditor"
      >
        <q-tooltip :delay="500">
          {{ $t('forms.table.btn.createFormFromJson') }}
        </q-tooltip>
      </q-btn>
    </div>
    <q-file ref="filePicker" v-model="file" class="hidden" accept=".json" />
    <q-dialog v-model="pasteJSONDialog">
      <q-card
        class="service-registry-json-dialog"
        :style="{ minWidth: '75vw' }"
      >
        <q-card-section class="text-h6">
          {{ $t('forms.JSONDialog.title') }}
        </q-card-section>
        <q-card-section class="q-pa-none">
          <v-json-editor
            ref="jsoneditor"
            v-model="rawJSON"
            height="500px"
            :options="{
              mode: 'code',
              mainMenuBar: false,
            }"
          />
        </q-card-section>
        <q-card-actions align="right">
          <q-btn
            color="negative"
            :label="$t('forms.JSONDialog.cancel')"
            @click="pasteJSONDialog = false"
          ></q-btn>
          <q-btn
            color="primary"
            :label="$t('forms.JSONDialog.create')"
            @click="createFromJSON"
          ></q-btn>
        </q-card-actions>
      </q-card>
    </q-dialog>
  </div>
</template>

<script lang="ts">
// @ts-ignore
import VJsonEditor from 'v-jsoneditor';
import { Component, Vue, Watch, Prop } from 'vue-property-decorator';
import isEmpty from 'lodash/isEmpty';
import FormGeneratorWrapper from '@components/common/node-generator/FormGeneratorWrapper.vue';
import head from 'lodash/head';
import get from 'lodash/get';
import { notifyError } from '@/utils/notify';
import { exportFile } from 'quasar';
import { FormApi } from '@openapi/registry-service';
import { unlink } from '@/services/registry-service';

const formApi = new FormApi();

@Component({
  components: {
    FormGeneratorWrapper,
    VJsonEditor,
  },
})
export default class ScreenFormEditor extends Vue {
  @Prop() schema: string;
  @Prop() formId: string;
  @Prop() formKey: string;
  @Prop() parentLinkedObject: any;

  form: any = null;
  previewMode: boolean = false;
  previewData: any = null;
  unsavedChanges: boolean = false;
  loading: boolean = false;
  file = null;
  pasteJSONDialog = false;
  rawJSON = {};

  created() {
    if (this.formId) {
      this.getForm();
    }
  }

  @Watch('formId')
  onFormChange(formId: string) {
    if (formId && !this.form) {
      this.getForm();
    }
  }

  @Watch('file')
  onFileChange(file: File) {
    if (!file) return;

    this.createFromFile(file);

    this.file = null;
  }

  get isAttrListEmpty() {
    return this.form?.attrList === undefined || isEmpty(this.form.attrList);
  }

  get doesFormExist() {
    return !isEmpty(this.form);
  }

  async createFromFile(file: File) {
    this.loading = true;

    const schemaStr = await file.text();

    await this.createFromString(schemaStr);

    //this.refresh(); get form / interagency again
  }

  pickFile() {
    const filePicker = this.$refs.filePicker as any;
    filePicker.pickFiles();
  }

  async getForm() {
    this.loading = true;
    try {
      const { data } = await formApi.getForm(this.formId);
      this.form = data;
    } catch (e) {
      if (e instanceof Error) {
        notifyError(e.message);
      }
    } finally {
      this.loading = false;
    }
  }

  getMockModel() {
    this.$store
      .dispatch('utils/components/fetchMockDataForSchema', this.form)
      .then((data) => {
        this.previewData = data.model;

        // Если на бфф есть не определенные типы в схеме, то выводим их
        if (Object.keys(data.warning).length > 0) {
          console.log(
            '[FormGenerator][Preview form] неизвестные типы схемы: ',
            data.warning
          );
        }
      });
  }

  changeMode() {
    this.previewMode = !this.previewMode;
    if (this.previewMode) {
      this.getMockModel();
    }
  }

  async saveSchema() {
    this.loading = true;
    try {
      const updatedSchema = {
        ...this.form,
        id: this.formId,
      };
      const { data } = await formApi.updateForm([updatedSchema]);
      if (data?.success) {
        this.form = updatedSchema;
      }
    } catch (e) {
      if (e instanceof Error) {
        notifyError(e.message);
      }
    } finally {
      this.loading = false;
    }
  }

  async createForm(schema: any) {
    this.loading = true;
    try {
      const { data } = await formApi.createForm([schema]);
      if (data?.success) {
        const form = { ...schema, id: head(get(data, 'objectIds')) };
        this.form = form;
        this.$emit('change', form.id);
      }
    } catch (e) {
      if (e instanceof Error) {
        notifyError(e.message);
      }
    } finally {
      this.loading = false;
    }
  }

  async deleteForm() {
    this.loading = true;
    try {
      unlink(this, this.schema, this.parentLinkedObject, this.formKey, this.formId)
        .then(({ data }: any) => {
          if (data.success) {
            return formApi.deleteForm([this.formId]);
          }
        })
        .then(() => {
          this.form = null;
          this.previewMode = false;
          this.$emit('change', '');
        });
    } catch (e) {
      if (e instanceof Error) {
        notifyError(e.message);
      }
    } finally {
      this.loading = false;
    }
  }

  edit() {
    this.$router.push({
      name: 'cards',
      params: {
        id: this.formId,
        path: 'schemas',
      },
      query: {
        components: 'index',
        backRoute: this.$route.fullPath
      },
    });
  }

  download() {
    if (!this.form) {
      notifyError(this.$tc('forms.errors.downloadForm'));

      return;
    }
    const schemaBlob = new Blob([JSON.stringify(this.form, null, 2)], {
      type: 'application/json',
    });

    exportFile(this.form.label + '.json', schemaBlob, 'application/json');
  }

  async createFromJSON() {
    await this.createFromString(JSON.stringify(this.rawJSON));
    //this.refresh();
  }

  createEmptyForm() {
    return {
      id: '',
      name: 'Interagencies',
      label: 'Запрос',
      attrList: [],
      groupList: [],
    };
  }

  async createFromString(schemaStr: any) {
    try {
      const name = 'Interagencies';
      const schema = JSON.parse(schemaStr);

      const attrListValid = schema.attrList && Array.isArray(schema.attrList);
      const groupListValid =
        schema.groupList && Array.isArray(schema.groupList);

      if (!attrListValid || !groupListValid) {
        const prefix = this.$t('forms.errors.schema.prefix');
        const suffix = !attrListValid
          ? this.$t('forms.errors.schema.attrSuffix')
          : this.$t('forms.errors.schema.groupSuffix');

        const message = `${prefix} ${suffix}`;

        throw new Error(message);
      }

      schema.name = schema.name || name;
      schema.label = 'Запрос';

      await this.createForm(schema);
    } catch (err) {
      if (err instanceof Error) {
        const message = err.message
          ? err.message
          : this.$tc('forms.errors.loadFile');

        notifyError(message);
      }

      console.error(
        '[service-constructor][forms][create from file] Could not parse file',
        { schemaStr },
        err
      );
    } finally {
      this.loading = false;
      this.pasteJSONDialog = false;
    }
  }

  launchJSONEditor() {
    this.rawJSON = this.createEmptyForm();
    this.pasteJSONDialog = true;
  }
}
</script>

<style scoped></style>
