<template lang="pug">
  medical-form-wrapper(
    id="documents",
    title="Документы",
    :is-check-change="isCheckChange",
    :is-edit="isEdit",
    :cancel="cancelEdit",
    :open-edit="openEdit",
    :save="saveChange"
  )
    q-form.form-wrap.gap-x-6.w-full(ref="documentForm", :no-error-focus="true")
      .data-section.flex.flex-col.gap-2(
        v-for="data in configData",
        :key="data.dataLabel",
        :class="data?.dataClass"
      )
        .font-semibold.text-sm.whitespace-nowrap {{data.dataLabel}}
        .flex.w-full.items-center.gap-4(
          v-for="field in data.fields",
          :key="field.label"
        )
          .label-field.font-sm.text-sm.whitespace-nowrap {{`${field.label} :`}}
          .flex.gap-3.items-center.h-10(v-if="field.type === 'photo'")
            q-avatar(
              rounded,
              size="40px",
              v-if="docData[data.dataKey]?.attachments?.photo"
            )
              img.h-10.w-10.object-cover(
                :src="docData[data.dataKey]?.attachments?.photo",
                :alt="docData[data.dataKey][field.label]"
              )
              q-badge.delete(
                floating,
                v-if="isEdit",
                rounded,
                @click="removeImage(data?.dataKey, field?.key)",
                :style="{padding: 0}"
              )
                q-icon.cancel-icon(name="app:cancel-mini", size="16px")
            .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-date(
            v-if="field.type === 'date'",
            v-model="docData[data.dataKey][field.key]",
            :name="data.dataKey + ':' + field.key",
            @update:model-value="checkChangeDocData",
            :readonly="!isEdit",
            width="100%",
            :mask="field?.inputMask",
            :rule="(val) => !personDataField.includes(data.dataKey + ':' + field.key) ? checkPassportFields(val, field.rules) : field.rules(val)",
            size="M",
          )
          base-input(
            v-if="field.type === 'text'",
            v-model="docData[data.dataKey][field.key]",
            :name="data.dataKey + ':' + field.key",
            @update:model-value="checkChangeDocData",
            :readonly="!isEdit",
            :type="field.type",
            width="100%",
            :mask="field?.inputMask",
            :rule="[(val) => !personDataField.includes(data.dataKey + ':' + field.key) ? checkPassportFields(val, field.rules) : field.rules(val, initialDocData?.[data.dataKey]?.id)]",
            size="M"
          )
            q-icon.my-auto.cursor-pointer.copy(
              size="20px",
              name="app:copy",
              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 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";
import BaseInput from "@/components/base/BaseInput.vue";
import BaseInputDate from "@/components/base/BaseInputDate.vue";
import { mapActions } from "vuex";
export default {
  name: "DocumentsForm",
  components: {
    MedicalFormWrapper,
    BaseInput,
    BaseAvatar,
    BaseModal,
    BaseUploadPhoto,
    TheNotificationProvider,
    BaseInputDate,
  },
  data() {
    return {
      configData: documentForm,
      isEdit: false,
      docData: null,
      isCheckChange: false,
      isLoadingData: true,
      copiedFields: [
        "series",
        "number",
        "insurance_number",
        "tax_identification_number",
      ],
      initializationData: {
        passport: {
          category: "passport",
          id: null,
          series: null,
          number: null,
          issued_by: null,
          issued_by_org_code: null,
          issued_at: null,
          attachments: null,
        },
        insurance_number: {
          id: null,
          category: "insurance_number",
          number: null,
          attachments: null,
        },
        tax_identification_number: {
          id: null,
          category: "tax_identification_number",
          number: null,
          attachments: null,
        },
      },
      personDataField: [
        "insurance_number:number",
        "tax_identification_number:number",
      ],
      showModal: false,
      photoId: "",
    };
  },
  computed: {
    initialDocData() {
      return this.$store.state.medical.documents;
    },
    passportFields() {
      let excludedFields = [
        "attachments",
        "id",
        "category",
        "issued_by_org_code",
      ];
      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.initialDocData.passport?.id
      ) {
        this.$refs.documentForm
          .getValidationComponents()
          .filter((elem) => !this.personDataField.includes(elem.name))
          .forEach((elem) => elem.resetValidation());
        return true;
      }
      return defaultRule(val);
    },
    removeImage(docKey, field) {
      this.docData[docKey][field] = {};
      this.checkChangeDocData();
    },
    copyValue(text) {
      navigator.clipboard.writeText(text);
    },
    checkCopiedFields(key) {
      return !this.isEdit && this.copiedFields.some((elem) => elem === key);
    },
    cancelEdit() {
      this.docData = this.destruct(this.initialDocData);
      this.isEdit = false;
      this.isCheckChange = false;
      this.$refs.documentForm.resetValidation();
    },
    openEdit() {
      this.isEdit = true;
    },
    checkChangeDocData() {
      this.isCheckChange = checkChangeData(
        this.destruct(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(({ dataKey, fields }) => {
              let findedElem = fields.find(
                (el) => dataKey + ":" + el.key === elem
              );
              if (findedElem) error = findedElem?.errorMessage;
            });
            this.addErrorNotification(error?.title, error?.message);
          });
        } else {
          let request = [];
          Object.keys(this.docData).forEach((elem) => {
            this.checkChangePhoto(elem, "attachments");
            let newData = JSON.parse(JSON.stringify(this.docData[elem]));
            newData.attachments = {};
            if (!checkChangeData(this.initialDocData?.[elem], newData)) return;
            delete newData.id;
            if (newData?.issued_by_org_code) {
              console.log(
                "passport issued_by_org_code",
                newData.issued_by_org_code
              );
              delete newData.issued_by_org_code;
            }
            delete newData.attachments;
            Object.keys(this.docData[elem])?.forEach((key) => {
              if (!this.docData[elem]?.[key]) delete newData?.[key];
            });
            if (!this.initialDocData?.[elem]?.id) {
              newData.person_id =
                this.$store.state.medical?.basicData?.personalData?.id;
              request.push(this.createData("documents/", newData));
            } else {
              request.push(
                this.updateData(
                  `documents/${this.initialDocData?.[elem]?.id}`,
                  newData
                )
              );
            }
          });
          Promise.allSettled(request).then(() => {
            this.getMedicalDataById(this.$route.params.id);
            this.isEdit = false;
            this.isCheckChange = false;
            this.$refs.form?.resetValidation();
          });
        }
      });
    },
    checkChangePhoto(updatedObjId, field) {
      if (this.docData[updatedObjId][field]?.file)
        console.log(
          updatedObjId,
          field,
          this.docData[updatedObjId][field]?.file[0]
        );
    },
    async createData(url, body) {
      return await fetchWrapper.post(url, body);
    },
    async updateData(url, body) {
      return await fetchWrapper.patch(url, body);
    },
    async deletePhoto(url) {
      return await fetchWrapper.del(url);
    },
    addErrorNotification(title, message) {
      addNotification(title + message, title, message, "error", 5000);
    },
    convertFormat(date) {
      return date ? date.split(".").reverse().join("-") : "";
    },
    ...mapActions({
      getMedicalDataById: "getMedicalDataById",
    }),
    destruct(data) {
      const { passport, insurance_number, tax_identification_number } =
        JSON.parse(JSON.stringify(data));
      return {
        passport: passport,
        insurance_number: insurance_number,
        tax_identification_number: tax_identification_number,
      };
    },
  },
  watch: {
    initialDocData: {
      deep: true,
      immediate: true,
      handler(value) {
        if (Object.keys(value).length) this.docData = this.destruct(value);
        else this.docData = this.initializationData;
      },
    },
  },
};
</script>
<style lang="sass" scoped>
.form-wrap
  display: grid
  grid-template-columns: repeat(3, 1fr)
  row-gap: 32px
  grid-template-rows: 1.2fr 1.8fr
  @media(max-width: 1440px)
    grid-template-columns: repeat(2, 1fr)
    grid-template-rows: 1.2fr 1.8fr
.label-field
  min-width: 110px
  color: var(--font-grey-color)
.replace-photo
  color: var(--btn-blue-color)
.photo-field
  min-width: 302px
.icon-copy .cursor
  cursor: pointer !important
.icon-cancel :deep(path)
  fill: var(--default-white)
.q-badge
  padding: 4px
  cursor: pointer
.delete
  background-color: var(--btn-red-color)
.cancel-icon :deep(path)
  fill: white
.copy :deep(path)
  fill: var(--font-grey-color)
.passport
  grid-column: 1 / 2
  grid-row: 1 / 3
.insurance
  grid-column: 2 / 3
  grid-row: 1 / 2
.tax
  grid-column: 2 / 3
  grid-row: 2 / 3
</style>
