<template>
  <div>
    <q-btn
      :disable="disableAllButtons || get(buttonSettings, 'props.disable')"
      class="q-ml-sm"
      outline
      :class="{ hidden: !get(buttonSettings, 'props.visible', true) }"
      @click="() => isModalOpen = true"
      v-bind="buttonSettings.props"
      :label="buttonSettings.props.label || buttonSettings.props.Buttonlable"
    />
    <q-dialog v-model="isModalOpen">
      <q-card class="q-pa-md" style="max-width: 600px; width: 600px;">
        <FormGeneratorWrapper
          v-if="schema && model"
          mode="edit"
          :model="formModel"
          :schema="schema"
          :hide-nulls="true"
          :padded-groups="true"
          class="q-mt-none"
        />

        <q-card-actions align="right">
          <q-btn
            color="primary"
            :label="buttonSettings.props.submitLable || 'Отправить'"
            @click="doAction"
          >

          </q-btn>
        </q-card-actions>

        <q-inner-loading :showing="loading">
          <q-spinner-gears color="primary" size="50px" />
        </q-inner-loading>
      </q-card>
    </q-dialog>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Prop, Watch } from 'vue-property-decorator';
import FormGeneratorWrapper from '@components/common/node-generator/FormGeneratorWrapper.vue';
import { BaseCardCommon } from '@/interfaces';
import get from 'lodash/get';
import { Form, FormApi } from '@openapi/registry-service';
import { notifyError } from '@/utils/notify';
import set from 'lodash/set';

const formApi = new FormApi();

function fillEmptyValues(attributes: any): any {
  const data = {};

  if (Array.isArray(attributes)) {
    attributes.forEach((element) => {
      let value;

      switch (element.type) {
        case 'string':
          if (element.view === 'carddictionary') {
            value = '1'; // Дефолтное значение словаря
          } else {
            value = '';
          }
          break;

        case 'boolean':
          value = false;
          break;

        case 'linkMN':
          value = element?.reference?.listAttrs
            ? [fillEmptyValues(element.reference.listAttrs)]
            : [];
          break;

        default:
          value = null;
          break;
      }

      set(data, element.name, value);
    });
  }

  return data;
};

function deepFill(obj1: any, obj2: any): void {
  // Проходимся по каждой паре ключ-значение в obj1
  for (const [key, value] of Object.entries(obj1)) {
    // Если значение - это объект, то вызываем deepFill на этот объект
    if (typeof value === "object" && !Array.isArray(value) && value) {
      deepFill(value, obj2[key]);
    }
    // Если ключ существует в obj2, то заменяем значение в obj1 значением из obj2
    else if (obj2.hasOwnProperty(key)) {
      obj1[key] = obj2[key];
    }
  }
};

@Component({
  components: {
    FormGeneratorWrapper,
  }
})
export default class CustomForm extends Vue {
  @Prop() common: BaseCardCommon;
  @Prop() model: any;
  @Prop() disableAllButtons: boolean;
  @Prop() userTask: any;
  @Prop() buttonSettings: any;

  loading = false;
  isModalOpen = false;
  schema: Form | null = null;
  formModel = {};
  get = get;

  @Watch('isModalOpen')
  onModalToggle(v: boolean) {
    if (v && !this.schema) {
      this.getForm();
    }

    if (v && this.schema) {
      this.fillModelValues();
    }
  }

  async getForm() {
    const formId = this.buttonSettings.props.FormId;
    if (!formId) {
      return;
    }

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

  doAction() {
    this.$emit('submit', {
      buttonId: this.buttonSettings.id,
      data: {
        ...this.formModel,
      },
    });
  }

  fillModelValues() {
    if (!this.schema) {
      return;
    }

    this.formModel = fillEmptyValues(this.schema.attrList);

    deepFill(this.formModel, this.model);
  }
}
</script>

<style scoped>

</style>