<template lang="pug">
  medical-form-wrapper(
    id="insurance",
    title="Страховка",
    :is-loading-data="isLoadingData",
    :is-check-change="isCheckChange",
    :is-edit="isEdit",
    :open-edit="openEdit",
    :save="saveChange",
    :cancel="cancelEdit"
  )
    q-form.form-wrap.gap-6.w-full(ref="insuranceForm", :no-error-focus="true")
      .flex.flex-col.gap-2(v-for="insurance in insuranceConfig", :key="insurance.insuranceKey")
        .font-semibold.text-sm.whitespace-nowrap {{insurance.insuranceLabel}}
        .flex.w-full.items-center.gap-4(
          v-for="field in insurance.fields",
          :key="insurance.insuranceKey + field.key",
          :style="{marginTop: field.label === 'Документы' ? '20px' : null}"
        )
          .label-field.font-sm.text-sm.whitespace-nowrap {{`${field.label} :`}}
          .flex.gap-3.items-center.h-10(
            v-if="field.type === 'photo'",
          )
            .flex.w-10.h-10.relative(v-if="insuranceData[insurance.insuranceKey]?.attachments?.photo")
              img.rounded.avatar.object-cover(
                :src="insuranceData[insurance.insuranceKey]?.attachments?.photo",
                alt="AV"
              )
              q-badge.delete(
                floating,
                v-if="isEdit",
                @click="removeImage(insurance?.insuranceKey, field?.key)",
                rounded,
                :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="changeModal(insurance.insuranceKey)"
            ) {{ insuranceData[insurance.insuranceKey]?.attachments?.photo ? "Заменить фото" : "Добавить фото" }}
            base-modal(
              v-if="insurance.insuranceKey === photoId"
              v-model="showModal",
              title="Загрузить изображение"
            )
              base-upload-photo(
                :key="insurance.insuranceKey"
                v-model="insuranceData[photoId][field.key]"
                :confirm-upload="confirmChangePhoto"
              )
          .flex.h-10.relative.gap-x-2.w-full(v-else-if="field.type === 'select'")
            .w-full.flex.items-center.change.px-4.rounded {{selectCategory(basic[insurance.insuranceKey][field.key])}}
            q-btn.change.flex.w-7.h-9.rounded-md(
              v-if="isEdit",
              @click="openModalCategories",
              dense,
              padding="8px"
            )
              q-icon.icon(name="app:folder", size="24px")
            base-modal(
              default-padding,
              hide-header,
              v-model="showModalCategories",
              title="Категории"
            )
              base-category-selection(
                :benefit-data="benefitData",
                :close-modal-categories="closeModalCategories",
                :save-categories="saveCategories",
                :show-modal="showModalCategories",
                :basic="basic.benefit",
                @search="filterDataBenefit"
              )
            .flex.font-medium.text-smm.absolute.top-11(
              v-if="basic?.benefit[insurance?.discount]",
              :style="{color: 'var(--font-grey-color)'}"
            )
              span Процент скидки:
              span(
                :style="{color: 'var(--font-dark-blue-color)'}"
              ) {{"\xa0" + basic?.benefit[insurance?.discount] + "%"}}
          .w-full.flex.flex-col.relative(v-else)
            base-input(
              v-model="insuranceData[insurance.insuranceKey][field.key]",
              @update:model-value="checkChangeInput",
              :readonly="!isEdit",
              size="M",
              width="100%",
              :name="insurance.insuranceKey + ':' + field.key",
              :rule="[(val) => checkFields(val, insurance.insuranceKey, field.rules)]"
            )
              q-icon.my-auto.cursor-pointer.copy(
                size="20px",
                name="app:copy",
                v-if="checkCopiedFields(field.key, insuranceData[insurance.insuranceKey])",
                @click="copyValue(insuranceData[insurance.insuranceKey][field.key])"
              )
</template>

<script>
import { baseInsuranceForm } from "@/pages/newMedicalCard/utils/medicalConfig";
import { mapActions, mapGetters, mapState } from "vuex";
import MedicalFormWrapper from "@/pages/newMedicalCard/components/MedicalFormWrapper.vue";
import BaseAvatar from "@/components/base/BaseAvatar.vue";
import { fetchWrapper } from "@/shared/fetchWrapper";
import BaseModal from "@/components/base/BaseModal.vue";
import BaseUploadPhoto from "@/components/base/BaseUploadPhoto.vue";
import BaseCategorySelection from "@/components/base/BaseCategorySelection.vue";
import { addNotification } from "@/components/Notifications/notificationContext";
import BaseInput from "@/components/base/BaseInput.vue";
import {
  checkChangeData,
  getFieldsNameUnvalidated,
} from "@/shared/utils/changesObjects.js";

export default {
  name: "InsuranceForm",
  components: {
    MedicalFormWrapper,
    BaseAvatar,
    BaseInput,
    BaseModal,
    BaseUploadPhoto,
    BaseCategorySelection,
  },
  data() {
    return {
      insuranceConfig: baseInsuranceForm,
      isCheckChange: false,
      isEdit: false,
      isLoadingData: false,
      showModal: false,
      showModalCategories: false,
      photoId: "",
      copiedFields: ["series", "number"],
      insuranceData: {},
      initializationData: {
        OMS: {
          category: "OMS",
          id: null,
          series: null,
          number: null,
          issued_by: null,
          issued_at: "",
          attachments: null,
        },
        DMS: {
          category: "OMS",
          id: null,
          series: null,
          number: null,
          issued_by: null,
          issued_at: "",
          attachments: null,
        },
      },
    };
  },
  computed: {
    ...mapGetters({
      url: "getUrl",
    }),
    ...mapState({
      basic: (state) => state.medical?.basicData,
      benefitData: (state) => state.medical?.benefitData,
    }),
    initialDocData() {
      return this.$store.state.medical.documents;
    },
  },
  methods: {
    checkFields(val, insuranceKey, defaultRule) {
      const filteredFields = ["series", "number"];
      if (
        filteredFields?.every(
          (elem) => !this.insuranceData?.[insuranceKey]?.[elem]
        ) &&
        !this.initialDocData?.[insuranceKey]?.id
      ) {
        this.$refs.insuranceForm
          .getValidationComponents()
          .filter(
            (elem) =>
              elem.name === `${insuranceKey}:series` ||
              elem.name === `${insuranceKey}:number`
          )
          .forEach((elem) => elem.resetValidation());
        return true;
      }
      return defaultRule(val);
    },
    filterDataBenefit(text) {
      if (text.length > 1)
        return this.$store.dispatch("getBenefitDataSearch", text);
      this.$store.dispatch("getBenefitData", text);
    },
    removeImage(docKey, field) {
      this.insuranceData[docKey][field] = {};
      this.checkChangeInput();
    },
    checkCopiedFields(key, item) {
      return (
        !this.isEdit &&
        this.copiedFields.some((elem) => elem === key) &&
        item[key]
      );
    },
    copyValue(text) {
      navigator.clipboard.writeText(text);
    },
    selectCategory(str) {
      if (str) return str.length > 30 ? str.substr(0, 30) + "..." : str;
      return "Выберите категорию";
    },
    saveCategories(obj) {
      this.showModalCategories = false;
      this.basic.benefit.id = obj.id;
      this.basic.benefit.name = obj.name;
      this.basic.benefit.discount = obj.discount;
      this.isCheckChange = true;
    },
    changeModal(id) {
      if (id === "benefit") return;
      this.photoId = id;
      this.showModal = true;
    },
    closeModalCategories() {
      this.showModalCategories = false;
    },
    openModalCategories() {
      //if (this.isEdit) this.showModalCategories = true;
    },
    checkChangeInput() {
      this.isCheckChange = checkChangeData(
        this.destruct(this.initialDocData),
        this.insuranceData
      );
    },
    confirmChangePhoto() {
      this.showModal = false;
      this.isCheckChange = true;
    },
    saveChange() {
      const form = this.$refs.insuranceForm;
      form.validate().then((validate) => {
        if (!validate) {
          getFieldsNameUnvalidated(form).forEach((elem) => {
            let error = {};
            this.insuranceConfig.forEach(({ insuranceKey, fields }) => {
              let findedElem = fields.find(
                (el) => insuranceKey + ":" + el.key === elem
              );
              if (findedElem) error = findedElem?.errorMessage;
            });
            this.addErrorNotification(error?.title, error?.message);
          });
        } else {
          let request = [];
          Object.keys(this.insuranceData).forEach((elem) => {
            this.checkChangePhoto(elem, "attachments");
            let newData = JSON.parse(JSON.stringify(this.insuranceData[elem]));
            newData.attachments = {};
            if (!checkChangeData(this.initialDocData?.[elem], newData)) return;
            delete newData.id;
            delete newData.attachments;
            Object.keys(this.insuranceData[elem])?.forEach((key) => {
              if (!this.insuranceData?.[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
                )
              );
          });
          if (request.length)
            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.insuranceData[updatedObjId][field]?.file)
        console.log(
          updatedObjId,
          field,
          this.insuranceData[updatedObjId][field]?.file[0]
        );
    },
    addErrorNotification(title, message) {
      addNotification(title + message, title, message, "error", 5000);
    },
    async createData(url, body) {
      return await fetchWrapper.post(url, body);
    },
    async updateData(url, body) {
      return await fetchWrapper.patch(url, body);
    },
    cancelEdit() {
      this.insuranceData = this.destruct(this.initialDocData);
      this.isEdit = false;
      this.isCheckChange = false;
    },
    openEdit() {
      this.isEdit = true;
    },
    destruct(data) {
      const { OMS, DMS } = JSON.parse(JSON.stringify(data));
      return {
        OMS: OMS,
        DMS: DMS,
      };
    },
    ...mapActions({
      getMedicalDataById: "getMedicalDataById",
    }),
  },
  watch: {
    showModalCategories: {
      immediate: true,
      handler(newVal) {
        if (newVal) this.$store.dispatch("getBenefitData");
      },
    },
    initialDocData: {
      deep: true,
      immediate: true,
      handler(newVal) {
        if (Object.keys(newVal).length) {
          this.insuranceData = this.destruct(newVal);
        } else this.insuranceData = this.initializationData;
      },
    },
  },
};
</script>

<style lang="sass" scoped>
.q-field :deep(.q-field__control)
  min-height: 40px
  width: 302px
  align-items: center
  background: rgba(0, 0, 0, 0.05)
  color: var(--font-dark-blue-color)

.avatar
  height: 100%

.replace-photo
  color: var(--btn-blue-color)

.form-wrap
  display: grid
  grid-template-columns: repeat(3, 1fr)
  grid-template-rows: repeat(1, 1fr)
  @media(max-width: 1440px)
    grid-template-columns: repeat(2, 1fr)
    grid-template-rows: 1.2fr 0.8fr

.label-field
  min-width: 110px
  color: var(--font-grey-color)

.q-badge
  padding: 4px
  cursor: pointer

.delete
  background-color: var(--btn-red-color)

.icon :deep(path)
  fill: var(--font-grey-color)

.icon-cancel :deep(path)
  fill: var(--default-white)

.copy :deep(path)
  fill: var(--font-grey-color)

.change
  background: var(--bg-light-grey)
  color: var(--font-grey-color)
  border: 1px solid var(--gray-secondary)

.q-field--outlined.q-field--readonly :deep(.q-field__control)
  background: var(--bg-light-grey) !important
  &:before
    border-color: var(--bg-light-grey) !important
    transition: none
  &:hover:before
    border-color: var(--bg-light-grey) !important

.q-field--outlined.q-field--readonly :deep(.q-field__native)
  cursor: default

.cancel-icon :deep(path)
  fill: white
</style>
