<template lang="pug">
  medical-form-wrapper(
    title="Документы",
    :is-check-change="isCheckChange",
    :is-edit="isEdit",
    :cancel="cancelEdit",
    :open-edit="openEdit",
    :save="saveChange"
  ) 
    q-form.form-wrap.gap-24.w-full(ref="documentForm", :no-error-focus="true")
      .data-section.flex.flex-col.gap-4(v-for="data in configData", :key="data.dataLabel")
        .font-semibold.text-sm.whitespace-nowrap {{data.dataLabel}}
        .flex.w-full.justify-between.items-center.gap-4(
          v-for="field in data.fields",
          :key="field.label"
        )
          .label-field.font-sm.text-sm.whitespace-nowrap {{`${field.label} :`}}
          .photo-field.flex.gap-3.items-center(v-if="field.type === 'photo'")
            q-avatar(
              square,
              size="40px",
              v-if="docData[data.dataKey][field.key]?.photo"
            )
              img.h-10.w-10.object-cover(
                :src="docData[data.dataKey][field.key]?.photo",
                :alt="docData[data.dataKey][field.label]"
              )
              q-badge.delete(
                floating,
                v-if="isEdit",
                rounded,
                @click="removeImage(data?.dataKey, field?.key)"
              )
                q-icon(name="app:icon-cancel", size="8px")
            .replace-photo.font-medium.text-base.cursor-pointer(
              v-if="isEdit",
              @click="openModal(data.dataKey)",
            ) {{ docData[data.dataKey][field.key]?.photo ? "Заменить фото" : "Добавить фото"}}
            base-modal(v-model="showModal", title="Загрузить изображение" v-if="photoId === data.dataKey")
              base-upload-photo(
                v-model="docData[photoId][field.key]",
                :confirm-upload="confirmChangePhoto",
              )
          base-input(
            v-else,
            v-model="docData[data.dataKey][field.key]",
            :name="field.key",
            @update:model-value="checkChangeDocData",
            :readonly="!isEdit",
            :type="field.type",
            textColor="var(--font-dark-blue-color)",
            :width="302",
            :standout="!isEdit",
            :outlined="isEdit", 
            :mask="field?.inputMask",
            :rule="[(val) => !personDataField.includes(field.key) ? checkPassportFields(val, field.rules) : field.rules(val)]",
            :autogrow="field.key === 'issued_by_org'"
          )
            .icon-copy.my-auto.text-lg.label-field(
              v-if="checkCopiedFields(field.key) && !!docData[data.dataKey][field.key]",
              @click="copyValue(docData[data.dataKey][field.key])"
            )
</template>

<script>
import MedicalFormWrapper from "@/pages/newMedicalCard/components/MedicalFormWrapper.vue";
import { documentForm } from "@/pages/newMedicalCard/utils/medicalConfig";
import BaseInput from "@/components/base/BaseInput.vue";
import BaseAvatar from "@/components/base/BaseAvatar.vue";
import BaseModal from "@/components/base/BaseModal.vue";
import BaseUploadPhoto from "@/components/base/BaseUploadPhoto.vue";
import {
  checkChangeData,
  getFieldsNameUnvalidated,
} from "@/shared/utils/changesObjects.js";
import { fetchWrapper } from "@/shared/fetchWrapper.js";
import TheNotificationProvider from "@/components/Notifications/TheNotificationProvider";
import { addNotification } from "@/components/Notifications/notificationContext";
export default {
  name: "DocumentsForm",
  components: {
    MedicalFormWrapper,
    BaseInput,
    BaseAvatar,
    BaseModal,
    BaseUploadPhoto,
    TheNotificationProvider,
  },
  data() {
    return {
      configData: documentForm,
      isEdit: false,
      docData: null,
      isCheckChange: false,
      isLoadingData: true,
      approvedPassportData: false,
      copiedFields: [
        "series",
        "number",
        "insurance_number",
        "tax_identification_number",
      ],
      initializationData: {
        passport: {
          id: null,
          series: null,
          number: null,
          issued_by_org: null,
          issued_by_org_code: null,
          issued_by_date: null,
          photo: null,
        },
        insurance_number: {
          insurance_number: null,
          photo_insurance_number: null,
        },
        tax_identification_number: {
          tax_identification_number: null,
          photo_tax_identification_number: null,
        },
      },
      personDataField: ["insurance_number", "tax_identification_number"],
      showModal: false,
      photoId: "",
    };
  },
  computed: {
    initialDocData() {
      return this.$store.state.medical?.documents;
    },
    passportFields() {
      let excludedFields = ["photo", "id"];
      return Object.keys(this.docData.passport).filter(
        (key) => !excludedFields.includes(key)
      );
    },
  },
  methods: {
    checkPassportFields(val, defaultRule) {
      if (this.passportFields.every((elem) => !this.docData.passport[elem])) {
        this.$refs.documentForm
          .getValidationComponents()
          .filter((elem) => !this.personDataField.includes(elem.name))
          .forEach((elem) => elem.resetValidation());
        this.approvedPassportData = true;
        return true;
      }
      this.approvedPassportData = false;
      return defaultRule(val);
    },
    removeImage(docKey, field) {
      this.docData[docKey][field] = {};
      this.isCheckChange = true;
    },
    copyValue(text) {
      navigator.clipboard.writeText(text);
    },
    checkCopiedFields(key) {
      return !this.isEdit && this.copiedFields.some((elem) => elem === key);
    },
    cancelEdit() {
      this.docData = JSON.parse(JSON.stringify(this.initialDocData));
      this.docData.passport.issued_by_date =
        this.initialDocData?.passport?.issued_by_date;
      this.isEdit = false;
      this.isCheckChange = false;
      this.$refs.documentForm.resetValidation();
    },
    openEdit() {
      this.isEdit = true;
    },
    checkChangeDocData() {
      this.isCheckChange = checkChangeData(this.initialDocData, this.docData);
    },
    openModal(id) {
      this.photoId = id;
      this.showModal = true;
    },
    confirmChangePhoto() {
      this.showModal = false;
      this.isCheckChange = true;
    },
    saveChange() {
      const form = this.$refs.documentForm;
      form.validate().then((validate) => {
        if (!validate) {
          getFieldsNameUnvalidated(form).forEach((elem) => {
            let error = {};
            this.configData.forEach(({ fields }) => {
              let findedElem = fields.find((el) => el.key === elem);
              if (findedElem) error = findedElem?.errorMessage;
            });
            this.addErrorNotification(error?.title, error?.message);
          });
        } else {
          let passportFormData = new FormData();
          let documentsFormData = new FormData();
          form.getValidationComponents().forEach((elem) => {
            if (!this.personDataField.includes(elem.name)) {
              if (!this.approvedPassportData)
                passportFormData.append(elem.name, elem.modelValue ?? "");
            } else documentsFormData.append(elem.name, elem.modelValue ?? "");
          });
          if (!this.approvedPassportData)
            this.checkChengePhoto("passport", "photo", passportFormData);
          this.checkChengePhoto(
            "insurance_number",
            "photo_insurance_number",
            documentsFormData
          );
          this.checkChengePhoto(
            "tax_identification_number",
            "photo_tax_identification_number",
            documentsFormData
          );
          let request = [];
          if (!this.approvedPassportData) {
            if (!this.initialDocData.passport?.id) {
              passportFormData.append("kind", "PASSPORT");
              passportFormData.append(
                "person",
                this.$store.state.medical?.basicData?.personalData?.id
              );
              request.push(
                this.sendData(
                  "general/identity_document/create/",
                  passportFormData
                )
              );
            } else
              request.push(
                this.sendData(
                  `general/identity_document/${this.initialDocData.passport?.id}/update/`,
                  passportFormData
                )
              );
          }
          request.push(
            this.sendData(
              `general/person/${this.$store.state.medical?.basicData?.personalData?.id}/update/`,
              documentsFormData
            )
          );
          Promise.allSettled(request).then(() => {
            this.$store.dispatch("getMedicalCardData");
            this.isEdit = false;
            this.isCheckChange = false;
            this.$refs.form?.resetValidation();
          });
        }
      });
    },
    checkChengePhoto(updatedObjId, field, formData) {
      if (this.docData[updatedObjId][field]?.file)
        formData.append(field, this.docData[updatedObjId][field]?.file[0]);
    },
    async sendData(url, body) {
      return await fetchWrapper.post(url, body, "formData");
    },
    addErrorNotification(title, message) {
      addNotification(title + message, title, message, "error", 5000);
    },
  },
  watch: {
    initialDocData: {
      deep: true,
      immediate: true,
      handler(value) {
        if (Object.keys(value).length) {
          this.docData = JSON.parse(JSON.stringify(this.initialDocData));
          this.docData.passport.issued_by_date =
            this.initialDocData?.passport?.issued_by_date;
        } else this.docData = this.initializationData;
      },
    },
  },
};
</script>
<style lang="sass" scoped>
.form-wrap
  display: grid
  grid-template-columns: repeat(3, 1fr)
  grid-template-rows: repeat(1, 1fr)
  @media(max-width: 1900px)
    grid-template-columns: repeat(2, 1fr)
    grid-template-rows: 2.5fr 0.5fr
  @media(max-width: 1320px)
    grid-template-columns: repeat(1, 1fr)
    grid-template-rows: 2.5fr 0.5fr 0.5fr
.label-field
  color: var(--font-grey-color)
.replace-photo
  color: var(--btn-blue-color)
.photo-field
  min-width: 302px
.icon-copy .cursor
  cursor: pointer !important
.q-badge
  padding: 4px
  cursor: pointer
.delete
  background-color: var(--btn-red-color)
</style>
