<template lang="pug">
  .wrapper.flex.relative
    .row-overlay.flex.justify-center.items-center.gap-x-2.text-base(
      v-if="rowOverlay",
    )
      button.recover-btn(@click="stopTimer") Восстановить
      .countdown 0:{{ countdown }}
    .row-wrapper.flex.flex-col.w-full(:class="closedDetail")
      .row-body.flex.w-full.cursor-pointer(
        :id="id",
        @click="(e) => openDetailInfo(e)",
        :class="{'row-overlay-color': rowOverlay}"
      )
        .dots-wrapper.flex.items-center.px-2
          q-btn(
            icon="app:icon-dots",
            size="12px",
            class="dots-button",
            @click.stop,
            v-if="!isOpenChange && !rowOverlay",
            round,
            dense,
            no-caps,
            padding="2px"
          )
            clients-action-popup(
              :open-change-data="openChangeData",
              :disabled-delete="!!deletedClientId && !rowOverlay",
              @delete-client="transmitDeleteClient",
              :create-medical-card="transmitMedicalCard"
            )
          q-btn(
            icon="app:icon-ok",
            size="8px",
            class="ok-button",
            v-if="isOpenChange && !rowOverlay",
            @click="closeChangeData",
            round,
            dense,
            no-caps,
            padding="4px 3px 2px 3px"
          )
        //- .check-box.flex.justify-center.items-center(
        //-   :class="{'row-opacity': rowOverlay}"
        //- )
        //-   clients-table-checkbox(
        //-     :id="id",
        //-     :check="check",
        //-     :is-check="isCheck"
        //-   )
        table-cell-body-name(
          :class="{'row-opacity': rowOverlay}"
          :value="dataClient",
          :avatar="dataClient.avatar",
          :avatar-color="dataClient.color",
          :photo="dataClient.photo",
          :url="url",
          :is-open-change="isOpenChange",
          :width="columnBody.find(el => el.name === 'fullName').width"
        )
        table-cell-body-birthday(
          v-if="!rowOverlay",
          :value="dataClient",
          :is-open-change="isOpenChange",
          :width="columnBody.find(el => el.name === 'age').width"
        )
        table-cell-body-priority(
          v-if="!rowOverlay",
          :value="dataClient",
          :choose-priority="choosePriority",
          :is-open-change="isOpenChange",
          :width="columnBody.find(el => el.name === 'priority').width"
        )
        table-cell-body-phone(
          v-if="!rowOverlay",
          :value="dataClient",
          :is-open-change="isOpenChange",
          :width="columnBody.find(el => el.name === 'phone').width"
        )
        table-cell-body-email(
          v-if="!rowOverlay",
          :value="dataClient",
          :is-open-change="isOpenChange",
          :width="columnBody.find(el => el.name === 'email').width"
        )
        table-cell-body-networks(
          v-if="!rowOverlay",
          :delete-network="deleteNetwork",
          :add-network="addNetwork",
          :networks="dataClient.contacts",
          :is-open-change="isOpenChange",
          :width="columnBody.find(el => el.name === 'networks').width"
        )
      client-detail-info-wrapper.detail.px-52px(
        :class="{'pb-[30px] pt-4': isOpenDetailInfo}"
        :data-address="dataAddress",
        :data-attachments="dataAttachments",
        :data-document="dataIdentityDocument",
        :data-notes="dataNotes"
        :save-new-doc="saveNewDoc",
        :delete-doc="deleteDoc",
        :delete-note="postDeleteNote"
        :update-document="postUpdateIdentityDocument",
        :update-address="postUpdateAddress",
        :update-notes="postUpdateNotes",
        :lack-data="lackData",
        :lack-address="lackAddress",
        :lack-attachments="lackAttachments",
        :lack-notes="lackNotes",
        :dope-address="dopeAddress",
        :create-address="postCreateAddress",
        :create-document="postCreateIdentityDocument",
        :create-note="postCreateNote",
        :address-id="addressId",
        :doc-id="docId",
      )
</template>

<script>
import TableCellBodyMeeting from "@/pages/clients/components/cells/TableCellBodyMeeting";
import TableCellBodyNetworks from "@/pages/clients/components/cells/TableCellBodyNetworks";
import TableCellBodyEmail from "@/pages/clients/components/cells/TableCellBodyEmail";
import TableCellBodyPhone from "@/pages/clients/components/cells/TableCellBodyPhone";
import TableCellBodyPriority from "@/pages/clients/components/cells/TableCellBodyPriority";
import TableCellBodyJobTitle from "@/pages/clients/components/cells/TableCellBodyJobTitle";
import TableCellBodyBirthday from "@/pages/clients/components/cells/TableCellBodyBirthday";
import TableCellBodyName from "@/pages/clients/components/cells/TableCellBodyName";
import ClientsActionPopup from "@/pages/clients/components/ClientsActionPopup";
import ClientsTableCheckbox from "@/pages/clients/components/ClientsTableCheckbox";
import ClientDetailInfoWrapper from "@/pages/clients/components/ClientDetailInfoWrapper";
import { fetchWrapper } from "@/shared/fetchWrapper";
import { column } from "@/pages/clients/utils/tableConfig";
import TheNotificationProvider from "@/components/Notifications/TheNotificationProvider";
import { addNotification } from "@/components/Notifications/notificationContext";
import * as moment from "moment";

export default {
  name: "ClientsTableRow",
  components: {
    ClientsTableCheckbox,
    ClientsActionPopup,
    TableCellBodyName,
    TableCellBodyBirthday,
    TableCellBodyJobTitle,
    TableCellBodyPriority,
    TableCellBodyPhone,
    TableCellBodyEmail,
    TableCellBodyNetworks,
    TableCellBodyMeeting,
    ClientDetailInfoWrapper,
    TheNotificationProvider,
  },
  data() {
    return {
      dataIdentityDocument: {},
      dataAddress: {},
      dataAttachments: [
        {
          initialization: true,
        },
      ],
      dataNotes: [
        {
          initialization: true,
        },
      ],
      isOpenDetailInfo: false,
      isOpenPopup: false,
      columnBody: column,
      prioritySettings: column.find((el) => el.name === "priority"),
      isOpenChange: false,
      dataClient: {},
      docId: "",
      addressId: "",
      lackData: true,
      lackAddress: true,
      lackAttachments: true,
      lackNotes: true,
      dopeAddress: {
        city: "",
        region: "",
        street: "",
        house: "",
        flat: "",
        index: "",
      },
      timer: null,
      countdown: 0,
    };
  },
  props: {
    id: String,
    check: Function,
    isCheck: Boolean,
    client: Object,
    deletedClientId: String,
    updateDataClient: Function,
    url: String,
    fetchDataClients: Function,
    createMedicalCard: Function,
    fetchCreatedClientData: Function,
    createdClientName: String,
  },
  computed: {
    rowOverlay() {
      return this.deletedClientId === this.client.id;
    },
    closedDetail() {
      return {
        "closed-detail": !this.isOpenDetailInfo,
      };
    },
  },
  methods: {
    stopTimer() {
      if (this.countdown !== 0) this.countdown = 0;
      this.$emit("recover-client");
      clearInterval(this.timer);
      this.timer = null;
    },
    startTimer() {
      this.countdown = 30;
      this.timer = setInterval(() => {
        this.changeCountdown();
      }, 1000);
    },
    changeCountdown() {
      if (this.countdown === 0) {
        this.deleteClient().then(() => {
          this.updateDataClient();
          this.stopTimer();
        });
      } else {
        this.countdown -= 1;
      }
    },
    postUpdateClient() {
      let foundElement = this.prioritySettings.settings.find(
        (el) => el.text === this.dataClient.priority
      );
      let data = {};
      let clientName = `${this.client.last_name || ""} ${
        this.client.first_name || ""
      } ${this.client.patronymic || ""}`;
      let age = this.dataClient.age
        ? moment(this.dataClient.age).format("YYYY-MM-DD")
        : null;

      if (!this.dataClient.fullName) this.dataClient.fullName = clientName;
      else if (this.dataClient.fullName !== clientName)
        data.full_name = this.dataClient.fullName;
      if (age !== this.client.birth_date && age) data.birth_date = age;
      else if (!age && this.client.birth_date) {
        this.addErrorNotification(
          "Некорректная дата рождения",
          "Пожалуйста, введите дату рождения корректно"
        );
        this.dataClient.age = this.client.birth_date
          ? new Date(this.client.birth_date)
          : null;
      }
      if (foundElement.id !== this.client.priority)
        data.priority = foundElement.id;
      if (
        data.birth_date &&
        moment(data.birth_date).isAfter(moment().format("YYYY-MM-DD"))
      ) {
        this.addErrorNotification(
          "Некорректная дата рождения",
          "Дата рождения позже текущего дня"
        );
        this.dataClient.age = this.client.birth_date
          ? new Date(this.client.birth_date)
          : null;
      } else if (Object.keys(data).length !== 0)
        fetchWrapper
          .post(`general/person/${this.client.id}/update/`, {
            ...data,
          })
          .then(() => {
            if (this.createdClientName) this.fetchCreatedClientData;
            else this.fetchDataClients();
          });
    },
    postContactsClient() {
      let contacts = [...this.dataClient.contacts];
      if (
        this.dataClient.email.username &&
        !contacts.find((el) => el.kind === "EMAIL")
      )
        contacts.push(this.dataClient.email);
      if (
        this.dataClient.phone.username &&
        this.dataClient.phone.username.length === 18 &&
        !contacts.find((el) => el.kind === "PHONE")
      )
        contacts.push(this.dataClient.phone);
      else if (
        this.dataClient.phone.username &&
        this.dataClient.phone.username.length < 18
      ) {
        this.dataClient.phone.username =
          this.client.contacts.find((el) => el.kind === "PHONE")?.username ||
          "";
        this.addErrorNotification(
          "Некорректный номер телефона",
          "Введите мобильный номер состоящий из 11 цифр"
        );
      }
      let mapCreateContacts = this.client.contacts.map((el) => el.kind);
      let mapDeleteContacts = contacts.map((el) => el.kind);
      let createContacts = contacts.filter((el) =>
        el.kind === "EMAIL" || el.kind === "PHONE"
          ? !mapCreateContacts.includes(el.kind)
          : el.kind
      );
      let deleteContacts = this.client.contacts.filter(
        (el) => !mapDeleteContacts.includes(el.kind)
      );
      let updateContacts = [];
      this.client.contacts.forEach((el) => {
        if (
          el.kind === "PHONE" &&
          this.dataClient.phone.username.length === 18 &&
          el.username !== this.dataClient.phone.username
        )
          updateContacts.push(this.dataClient.phone);
        else if (
          el.kind === "PHONE" &&
          this.dataClient.phone.username &&
          this.dataClient.phone.username.length < 18
        ) {
          this.dataClient.phone.username =
            this.client.contacts.find((el) => el.kind === "PHONE")?.username ||
            "";
          this.addErrorNotification(
            "Некорректный номер телефона",
            "Введите мобильный номер состоящий из 11 цифр"
          );
        }
        if (
          el.kind === "EMAIL" &&
          el.username !== this.dataClient.email.username
        )
          updateContacts.push(this.dataClient.email);
      });
      createContacts.forEach((el) => {
        if (!el.id) this.postCreateContact(el);
      });
      deleteContacts.forEach((el) => this.postDeleteContact(el));
      updateContacts.forEach((el) => this.postUpdateContact(el));
    },
    postCreateContact(contact) {
      fetchWrapper
        .post("general/contact/create/", {
          kind: contact.kind,
          username: contact.username,
          person: this.client.id,
        })
        .then(() => {
          if (this.createdClientName) this.fetchCreatedClientData;
          else this.fetchDataClients();
        });
    },
    postUpdateContact(contact) {
      fetchWrapper
        .post(`general/contact/${contact.id}/update/`, {
          kind: contact.kind,
          username: contact.username,
          person: this.client.id,
        })
        .then(() => {
          if (this.createdClientName) this.fetchCreatedClientData;
          else this.fetchDataClients();
        });
    },
    postDeleteContact(contact) {
      fetchWrapper.del(`general/contact/${contact.id}/delete/`).then(() => {
        if (this.createdClientName) this.fetchCreatedClientData;
        else this.fetchDataClients();
      });
    },
    addNetwork(network) {
      this.dataClient.contacts.push({
        kind: network.kind?.id,
        username: network.username,
      });
    },
    deleteNetwork(e) {
      this.dataClient.contacts = this.dataClient.contacts.filter(
        (el) => el.kind !== e.currentTarget.id
      );
    },
    choosePriority(e) {
      this.dataClient.priority = this.columnBody
        .find((el) => el.name === "priority")
        ["settings"].find((el) => el.text === e.target.id).priority;
    },
    closeChangeData(e) {
      e.stopPropagation();
      this.isOpenChange = false;
      this.postUpdateClient();
      this.postContactsClient();
    },
    openChangeData() {
      this.isOpenChange = true;
    },
    transmitMedicalCard() {
      this.$emit(
        "handler-click-popup",
        "medical",
        this.client.id,
        this.client?.medical_history?.find((elem) => elem?.id)?.id
      );
    },
    transmitDeleteClient() {
      this.isOpenDetailInfo = false;
      this.$emit("handler-click-popup", "delete", this.client.id);
    },
    async deleteClient() {
      await fetchWrapper.del(`general/person/${this.client.id}/delete/`);
      this.addSuccessNotification("Клиент успешно удален", "");
      this.handleUnFocusPopup();
    },
    addSuccessNotification(title, message) {
      addNotification(new Date().getTime(), title, message, "success", 5000);
    },
    addErrorNotification(title, message) {
      addNotification(title, title, message, "error", 5000);
    },
    fetchClientDetail(id) {
      fetchWrapper.get(`general/person/${id}/detail/`).then((data) => {
        this.saveClientDetail(data);
        this.saveNote(data);
      });
      this.fetchAttachment();
    },
    saveClientDetail(data) {
      this.saveIdentityDocument(
        data.identity_documents.find(
          (el) => el.kind === "Паспорт" || el.kind === "PASSPORT"
        )
      );
      this.saveAddress(data.address[0]);
    },
    fetchAttachment() {
      fetchWrapper
        .get("general/attachment/?limit=1000")
        .then((data) => this.saveAttachment(data.results));
    },
    saveAttachment(data) {
      this.dataAttachments = data.filter((e) => e.person.id === this.id);
      this.lackAttachments = this.dataAttachments[0]?.id ? true : false;
    },
    saveNote(data) {
      this.dataNotes = data?.note.filter((e) => !e?.deleted_flg);
      if (this.dataNotes[0]) {
        this.lackNotes = true;
      } else {
        this.lackNotes = false;
        this.dataNotes = [{ title: "", description: "" }];
      }
    },
    saveIdentityDocument(data) {
      if (data?.id) {
        this.docId = data.id;
        this.dataIdentityDocument = {
          number:
            data.series && data.number ? data?.series + " " + data?.number : "",
          issued_by_org: data.issued_by_org ? data?.issued_by_org : "",
          issued_by_org_code: data.issued_by_org_code
            ? data?.issued_by_org_code
            : "",
          issued_by_date: data.issued_by_date
            ? new Date(data?.issued_by_date)
            : null,
        };
        this.lackData = true;
      } else {
        this.lackData = false;
        this.dataIdentityDocument = {
          number: "",
          issued_by_org: "",
          issued_by_org_code: "",
          issued_by_date: null,
        };
      }
    },
    postUpdateIdentityDocument() {
      fetchWrapper
        .post(`general/identity_document/${this.docId}/update/`, {
          kind: "PASSPORT",
          series_number: this.dataIdentityDocument.number,
          issued_by_org: this.dataIdentityDocument.issued_by_org,
          issued_by_org_code: this.dataIdentityDocument.issued_by_org_code,
          issued_by_date: moment(
            this.dataIdentityDocument.issued_by_date
          ).format("YYYY-MM-DD"),
        })
        .then((response) => {
          this.fetchClientDetail(this.id);
          if (response.type) {
            if (response.errors[0].code === "blank")
              this.addErrorNotification(
                "Ошибка редактрирования ДУЛ",
                "Часть паспортных данных не заполнена"
              );
            if (response.errors[0].code === "Ошибка редактирования ДУЛ")
              this.addErrorNotification(
                response.errors[0].code,
                response.errors[0].detail
              );
            if (response?.errors[0].code === "invalid")
              this.addErrorNotification(
                "Ошибка редактрирования ДУЛ",
                "Дата выдачи паспорта не заполнена"
              );
          } else this.addSuccessNotification("Изменения успешно сохранены", "");
        });
    },
    saveAddress(data) {
      this.addressId = data?.id;
      if (data?.full_address) {
        this.dataAddress = {
          full_address: data.full_address,
        };
        this.lackAddress = true;
      } else {
        this.lackAddress = false;
        this.dataAddress = {
          full_address: "",
        };
      }
    },
    mergeFullAddress() {
      if (
        this.dopeAddress.region &&
        this.dopeAddress.city &&
        this.dopeAddress.street &&
        this.dopeAddress.house
      ) {
        return `${this.dopeAddress.index}, ${this.dopeAddress.region} обл., г.${this.dopeAddress.city}, ул.${this.dopeAddress.street}, д.${this.dopeAddress.house}, кв.${this.dopeAddress.flat}`;
      }
    },
    clearAddress() {
      this.dopeAddress = {
        city: "",
        region: "",
        street: "",
        flat: "",
        house: "",
        index: "",
      };
    },
    postUpdateAddress() {
      fetchWrapper
        .post(`general/address/${this.addressId}/update/`, {
          full_address:
            this.mergeFullAddress() || this.dataAddress.full_address,
        })
        .then((response) => {
          this.fetchClientDetail(this.id);
          if (response.type && response.errors[0].code === "blank")
            this.addErrorNotification(
              "Ошибка именения адреса",
              "Полный адрес не заполнен"
            );
          else this.addSuccessNotification("Изменения успешно сохранены", "");
        });
      this.clearAddress();
    },
    openPopup(e) {
      e.target.focus();
      e.stopPropagation();
      this.isOpenPopup = !this.isOpenPopup;
    },
    openDetailInfo(e) {
      if (!this.isOpenDetailInfo)
        this.$store.state.currentPatient = this.client;
      else this.$store.state.currentPatient = {};
      this.isOpenDetailInfo = !this.isOpenDetailInfo;
      this.isOpenDetailInfo && this.fetchClientDetail(e.currentTarget.id);
    },
    handleUnFocusPopup() {
      this.isOpenPopup = false;
    },
    saveNewDoc(data) {
      this.dataAttachments = [...data];
      const formData = new FormData();
      this.dataAttachments.forEach((e) => {
        formData.append("person", this.id);
        formData.append("document", e);
        formData.append("title", e.name.substr(0, e.name.lastIndexOf(".")));
        fetchWrapper
          .post("general/attachment/create/", formData, "formData")
          .then(() => this.fetchClientDetail(this.id));
      });
    },
    deleteDoc(attachmentId) {
      fetchWrapper
        .del(`general/attachment/${attachmentId}/delete/`)
        .then(() => this.fetchClientDetail(this.id));
    },
    postCreateAddress() {
      fetchWrapper
        .post("general/address/create/", {
          person: this.id,
          full_address:
            this.mergeFullAddress() || this.dataAddress.full_address,
        })
        .then((response) => {
          this.fetchClientDetail(this.id);
          if (response.type && response.errors[0].code === "blank")
            this.addErrorNotification(
              "Ошибка создания адреса",
              "Полный адрес не заполнен"
            );
          else this.addSuccessNotification("Полный адрес успешно создан", "");
        });
    },
    postCreateIdentityDocument() {
      fetchWrapper
        .post("general/identity_document/create/", {
          person: this.id,
          kind: "PASSPORT",
          series_number: this.dataIdentityDocument.number,
          issued_by_org: this.dataIdentityDocument.issued_by_org,
          issued_by_org_code: this.dataIdentityDocument.issued_by_org_code,
          issued_by_date: moment(
            this.dataIdentityDocument.issued_by_date
          ).format("YYYY-MM-DD"),
        })
        .then((response) => {
          this.fetchClientDetail(this.id);
          if (response.type) {
            if (response.errors[0].code === "blank")
              this.addErrorNotification(
                "Ошибка создания ДУЛ",
                "Часть паспортных данных не заполнена"
              );
            if (response.errors[0].code === "Ошибка создания ДУЛ")
              this.addErrorNotification(
                response.errors[0].code,
                response.errors[0].detail
              );
            if (response.errors[0].code === "invalid")
              this.addErrorNotification(
                "Ошибка создания ДУЛ",
                "Дата выдачи паспорта не заполнена"
              );
          } else
            this.addSuccessNotification(
              "Паспортные данные успешно созданы",
              ""
            );
        });
    },
    postCreateNote(title, description) {
      if (!title || !description) {
        this.addErrorNotification(
          "Ошибка создания дополнительных данных",
          "Все поля должны быть заполнены"
        );
      } else
        fetchWrapper
          .post("general/note/create/", {
            person: this.id,
            title: title,
            description: description,
          })
          .then(() => this.fetchClientDetail(this.id));
    },
    postUpdateNotes() {
      this.dataNotes.forEach((e) => {
        if (!e.title || !e.description) {
          this.addErrorNotification(
            "Ошибка изменения дополнительных данных",
            "Поля не могут быть пустыми"
          );
          this.fetchClientDetail(this.id);
        } else
          fetchWrapper
            .post(`general/note/${e.id}/update/`, {
              title: e.title,
              description: e.description,
            })
            .then(() => this.fetchClientDetail(this.id));
      });
    },
    postDeleteNote(noteId) {
      fetchWrapper
        .del(`general/note/${noteId}/delete/`)
        .then(() => this.fetchClientDetail(this.id));
    },
  },

  watch: {
    rowOverlay() {
      if (this.rowOverlay) this.startTimer();
    },
    client: {
      deep: true,
      immediate: true,
      handler(newValue) {
        if (newValue) {
          this.dataClient = {
            id: this.client.id,
            fullName: `${this.client.last_name || ""} ${
              this.client.first_name || ""
            } ${this.client.patronymic || ""}`,
            age: this.client.birth_date
              ? new Date(this.client.birth_date)
              : null,
            priority: this.prioritySettings.settings.find(
              (el) =>
                el.priority === this.client.priority ||
                this.client.priority === el.id
            )?.text,
            phone: {
              id:
                this.client.contacts.find((el) => el.kind === "PHONE")?.id ||
                "",
              kind: "PHONE",
              username:
                this.client.contacts.find((el) => el.kind === "PHONE")
                  ?.username || "",
            },
            email: {
              id:
                this.client.contacts.find((el) => el.kind === "EMAIL")?.id ||
                "",
              kind: "EMAIL",
              username:
                this.client.contacts.find((el) => el.kind === "EMAIL")
                  ?.username || "",
            },
            contacts: this.client.contacts.filter(
              (el) =>
                !el.deleted_flg && el.kind !== "EMAIL" && el.kind !== "PHONE"
            ),
            avatar: this.client.first_name
              ? this.client.last_name[0] + this.client.first_name[0]
              : this.client.last_name.substr(0, 2),
            color: this.client?.color,
            photo: this.client?.photo,
          };
        }
      },
    },
  },
  beforeUnmount() {
    if (this.timer) {
      this.deleteClient();
      this.stopTimer();
    }
  },
};
</script>

<style lang="sass" scoped>
.row-wrapper
  border-bottom: 1px solid var(--border-light-grey-color)
  min-width: 1556px
.row-wrapper:hover
  background-color: var(--bg-hover-row-table)
.row-body
  color: var(--font-dark-blue-color)
  min-height: 56px
.check-box
  min-width: 36px
.dots
  min-width: 14px
.dots-button
  color: var(--font-grey-color)
  &:hover
    background-color: var(--btn-blue-color)
    color: var(--default-white)
.ok-button
  color: var(--btn-blue-color)
  border: 2px solid var(--btn-blue-color)
  &:hover
    background-color: var(--btn-blue-color)
    color: var(--default-white)
  &:active
    background-color: var(--btn-light-green-color)
    color: var(--btn-green-color)
    border-color: var(--btn-light-green-color)
.row-opacity
  opacity: 0.5
.row-overlay
  background: transparent
  position: absolute
  z-index: 10
  width: 100%
  height: 100%
.row-overlay-color
  background: var(--row-overlay-color)
.recover-btn
  color: var(--btn-blue-color)
.countdown
  color: var(--font-grey-color )
.detail
  max-height: 560px
  transition: 0.3s ease all
  overflow: hidden
.closed-detail .detail
  max-height: 0
.dots-wrapper
  width: 53px
</style>
