<template>
  <div class="q-pa-lg">
    
    <q-toolbar class="bg-primary text-white">
      <q-toolbar-title class="text-h6 q-bold">
        Finalizar pedido #{{ order.id }}
      </q-toolbar-title>
      <q-btn v-close-popup icon="close" flat dense>Fechar</q-btn>
    </q-toolbar>

    <q-stepper 
      animated
      alternative-labels
      header-nav
      flat
      v-model="current"
      ref="stepper"
      color="primary"
      :vertical="$q.screen.lt.sm"
    >
      <q-step
        :header-nav="steps.retrieve.hasErrors === false"
        name="retrieve"
        title="Dados de coleta"
        icon="business"
        :done="steps.retrieve.hasErrors === false"
        :error="steps.retrieve.hasErrors === true"
      >
        <Retrieve
          ref="retrieveForm"
          :quoteContact="quoteContact"
          :order="order"
          :steps="data"
          :extra="steps.retrieve.extra"
          @saved="goToNext"
        />
      </q-step>

      <q-step
        :header-nav="steps.delivery.hasErrors === false"
        name="delivery"
        title="Dados de entrega"
        icon="business"
        :done="steps.delivery.hasErrors === false"
        :error="steps.delivery.hasErrors === true"
      >
        <Delivery
          ref="deliveryForm"
          :quoteContact="quoteContact"
          :order="order"
          :steps="data"
          :extra="steps.delivery.extra"
          @saved="goToNext"
        />
      </q-step>

      <q-step
        :header-nav="steps.summary.hasErrors === false"
        name="summary"
        title="Informações adicionais"
        icon="business"
        :done="steps.summary.hasErrors === false"
        :error="steps.summary.hasErrors === true"
      >
        <Summary
          ref="summaryForm"
          :order="order"
          :steps="data"
          :extra="steps.summary.extra"
          @saved="goToNext"
        />
      </q-step>
    </q-stepper>
  </div>
</template>

<script>
import { mapActions, mapGetters } from "vuex";

import Retrieve from "./Retrieve";
import Delivery from "./Delivery";
import Summary from "./Summary";

export default {
  components: {
    Retrieve,
    Delivery,
    Summary,
  },

  props: {
    order: {
      type: Object,
      required: true,
    },
    quoteContact: {
      type: Object,
      required: false,
    },
    selectedQuoteId: {
      type: [String, Number],
      required: false,
      default: null,
    },
  },

  mounted() {
    this.syncSelectedQuoteId();
    this.$emit("load");
  },

  data() {
    return {
      current: "retrieve",
      steps: {
        retrieve: {
          hasErrors: null,
          extra: {},
        },
        delivery: {
          hasErrors: null,
          extra: {},
        },
        summary: {
          hasErrors: null,
          extra: {},
        },
      },
      data: {
        retrieve: { id: null },
        delivery: { id: null },
        summary: { id: null },
      },
      lockedQuoteId: null,
    };
  },

  computed: {
    ...mapGetters({
      myCompany: "people/currentCompany",
      defaultCompany: "people/defaultCompany",
      loggedUser: "auth/user",
    }),
  },

  watch: {
    selectedQuoteId: function () {
      this.syncSelectedQuoteId();
    },
    "order.choose": function () {
      this.syncSelectedQuoteId();
    },
    "order.quote": function () {
      this.syncSelectedQuoteId();
    },
  },

  methods: {
    ...mapActions({
      choose_retrieve_quote: "quote/choose_retireve_quote",
      choose_delivery_quote: "quote/choose_delivery_quote",
      choose_payer_quote: "quote/choose_payer_quote",
      choose_payment_quote: "quote/choose_payment_quote",
      email: "people/email",
      contact: "people/createContact",
      contactSearch: "people/contact",
    }),

    syncSelectedQuoteId() {
      const selected =
        this.selectedQuoteId
          ? this.selectedQuoteId
          : this.order && this.order.choose
          ? this.order.choose
          : this.order && this.order.quote && this.order.quote.id
          ? this.order.quote.id
          : null;
      this.lockedQuoteId = selected;
      return selected;
    },

    resolveExistingContact(payload) {
      const params = {};
      if (payload && payload.contact && payload.contact.id) {
        params.id = payload.contact.id;
      }
      if (payload && payload.contact && payload.contact.email) {
        params.email = payload.contact.email;
      }
      if (payload && payload.document) {
        params.document = payload.document;
      }
      if (this.myCompany && this.myCompany.id) {
        params.myCompany = this.myCompany.id;
      }

      if (Object.keys(params).length === 0) {
        return Promise.resolve(false);
      }

      return this.contactSearch({ params }).then((response) => {
        const data = response && response.data ? response.data : null;
        if (!data) return false;

        const companyFromData =
          data && data.companies ? (Array.isArray(data.companies) ? data.companies[0] : null) : null;
        if (!this.data[this.current].id && companyFromData && companyFromData.id) {
          this.data[this.current].id = companyFromData.id;
        } else if (!this.data[this.current].id && data.id) {
          this.data[this.current].id = data.id;
        }

        const contacts = Array.isArray(data.contact)
          ? data.contact
          : data.contact
          ? [data.contact]
          : [];
        const chosen = contacts.length > 0 ? contacts[0] : null;

        if (chosen && chosen.id) {
          this.data[this.current].contact.id = chosen.id;
          return true;
        }
        return false;
      });
    },

    createContact() {
      let payload = this.data[this.current];
      const contactName =
        payload.contact && payload.contact.name
          ? payload.contact.name
          : payload.personType === "PF"
          ? payload.name
          : null;

      let p = [];
      if (payload.contact && contactName) {
        p = {
          companyId: payload.id || null,
          name: payload.name,
          alias: payload.alias,
          document: payload.document,
          contact: {
            name: contactName,
            email: payload.contact.email,
            phone: payload.contact.phone,
          },
          whereRetrieve: payload.extra.whereRetrieve,
          whereDelivery: payload.extra.whereDelivery,
          personType: payload.personType,
          address: {
            country: payload.address.country,
            state: payload.address.state,
            city: payload.address.city,
            district: payload.address.district,
            complement: payload.address.complement,
            street: payload.address.street,
            number: payload.address.number,
            postal_code: payload.address.postal_code,
          },
        };
      } else {
        p = payload;
      }

      return this.resolveExistingContact(p)
        .then((resolved) => {
          if (resolved) return true;
          return this.contact(p).then((response) => {
            let formHasErrors = !(response && response.success === true);

            if (formHasErrors) {
              const errorMsg = response && response.error ? response.error : "";
              const isAlreadyInUse =
                /document.*already in use/i.test(errorMsg) ||
                /documento.*uso/i.test(errorMsg) ||
                /documento.*ja.*existe/i.test(errorMsg) ||
                /já.*existe/i.test(errorMsg);
              if (isAlreadyInUse) {
                return this.resolveExistingContact(p).then((retryResolved) => {
                  if (retryResolved) return true;
                  this.notifyError(errorMsg);
                  this.steps[this.current].hasErrors = true;
                  return false;
                });
              }
              this.notifyError(errorMsg);
              this.steps[this.current].hasErrors = true;
              return false;
            }
            //this.data[this.current].id = response.data.companyId;
            if (!this.data[this.current].id && response.data.companyId) {
              this.data[this.current].id = response.data.companyId;
            }
            this.data[this.current].contact.id = response.data.contactId;
            return true;
          });
        })
        .catch((error) => {
          this.notifyError(error.message);
        });
    },

    goToNext(form) {
      this.steps[this.current].hasErrors = form.errors;
      this.steps[this.current].extra = form.extra || null;
      // if no errors

      if (form.errors === false) {
        let id = this.data[this.current].id;
        // save temp data
        this.data[this.current] = form.data;
        if (!form.data.id) this.data[this.current].id = id;
        this.data[this.current].extra = form.extra;

        const shouldSkipContact =
          form.extra && form.extra.noRecipientContactData === true;

        if (
          this.current != "summary" &&
          !shouldSkipContact &&
          (!this.data[this.current].contact ||
            !this.data[this.current].contact.id)
        ) {
          this.resolveExistingContact(this.data[this.current]).then((resolved) => {
            if (resolved) {
              if (this.current == "retrieve") {
                this.saveRetrieve(form);
              }
              if (this.current == "delivery") {
                this.saveDelivery(form);
              }
              if (this.current == "summary") {
                if (this.defaultCompany.domainType == "ceg") {
                  this.savePaymentType(form);
                } else {
                  this.savePayer(form);
                }
              }
              return;
            }
            this.createContact().then((result) => {
              if (result === true) {
                if (this.current == "retrieve") {
                  this.saveRetrieve(form);
                }
                if (this.current == "delivery") {
                  this.saveDelivery(form);
                }
                if (this.current == "summary") {
                  if (this.defaultCompany.domainType == "ceg") {
                    this.savePaymentType(form);
                  } else {
                    this.savePayer(form);
                  }
                }
              }
            });
          });
        } else {
          if (this.current == "retrieve") {
            this.saveRetrieve(form);
          }
          if (this.current == "delivery") {
            this.saveDelivery(form);
          }
          if (this.current == "summary") {
            if (this.defaultCompany.domainType == "ceg") {
              this.savePaymentType(form);
            } else {
              this.savePayer(form);
            }
          }
        }
      }
    },
    saveRetrieve(form) {
      const selectedQuoteId = this.lockedQuoteId || this.syncSelectedQuoteId();
      const hasNoContact =
        form.extra && form.extra.noRecipientContactData === true;
      const retrievePeopleId =
        (this.data.retrieve && this.data.retrieve.id) ||
        form.data.id ||
        (!hasNoContact &&
        this.data.retrieve &&
        this.data.retrieve.contact &&
        this.data.retrieve.contact.id
          ? this.data.retrieve.contact.id
          : null);

      let payload = {
        id: this.order.id,
        values: {
          quote: selectedQuoteId,
          document: form.data.document,
          retrieve: {
            name: form.data.name,
            alias: form.data.alias,
            document: form.data.document,
            personType: form.personType
              ? form.personType
              : form.extra.personType,
            whereRetrieve: form.extra.whereRetrieve,
            whereDelivery: form.extra.whereDelivery,
            id: retrievePeopleId,
            address: this.data.retrieve.address,
            contact: hasNoContact ? null : this.data.retrieve.contact.id,
          },
        },
      };

      payload.query = {};
      if (this.myCompany !== null) {
        payload.query.myCompany = this.myCompany.id;
      }

      this.choose_retrieve_quote(payload)
        .then((response) => {
          if (!response["@id"]) {
            if (form.hasCallback) {
              form.hasCallback();
            }

            if (response && response.response && response.response.error) {
              this.notifyError(this.$t(response.response.error));
            } else {
              this.notifyError(
                "Não foi possivel finalizar o checkout, verifique se você tem permissão ou tente novamente mais tarde."
              );
            }
          } else {
            if (!this.data.retrieve.id) {
              this.data.retrieve.id = response["retrieve_people"];
            }
            this.$refs.stepper.next();
          }
        })
        .catch((e) => {
          if (form.hasCallback) {
            form.hasCallback();
          }
          if (e && e.response && e.response.error) {
            this.notifyError(this.$t(e.response.error));
          } else if (e && e.message) {
            this.notifyError(e.message);
          } else {
            this.notifyError(
              "Não foi possivel finalizar o checkout, verifique se você tem permissão ou tente novamente mais tarde."
            );
          }
        });
    },
    saveDelivery(form) {
      const selectedQuoteId = this.lockedQuoteId || this.syncSelectedQuoteId();
      const hasNoContact =
        form.extra && form.extra.noRecipientContactData === true;
      const deliveryPeopleId =
        (this.data.delivery && this.data.delivery.id) ||
        form.data.id ||
        (!hasNoContact &&
        this.data.delivery &&
        this.data.delivery.contact &&
        this.data.delivery.contact.id
          ? this.data.delivery.contact.id
          : null);
      const deliveryContactId =
        hasNoContact
          ? null
          : this.data.delivery &&
            this.data.delivery.contact &&
            this.data.delivery.contact.id
          ? this.data.delivery.contact.id
          : this.data.delivery.id;

      let payload = {
        id: this.order.id,
        values: {
          quote: selectedQuoteId,
          document: form.data.document,
          delivery: {
            name: form.data.name,
            alias: form.data.alias,
            document: form.data.document,
            personType: form.personType
              ? form.personType
              : form.extra.personType,
            whereRetrieve: form.extra.whereRetrieve,
            whereDelivery: form.extra.whereDelivery,
            id: deliveryPeopleId,
            address: this.data.delivery.address,
            contact: deliveryContactId,
          },
        },
      };

      payload.query = {};
      if (this.myCompany !== null)
        payload.query = {
          myCompany: this.myCompany.id,
        };

      this.choose_delivery_quote(payload)
        .then((response) => {
          if (!response["@id"]) {
            if (form.hasCallback) {
              form.hasCallback();
            }
            if (response && response.response && response.response.error) {
              this.notifyError(this.$t(response.response.error));
            } else {
              this.notifyError(
                "Não foi possivel finalizar o checkout, verifique se você tem permissão ou tente novamente mais tarde."
              );
            }
          } else {
            if (!this.data.delivery.id) {
              this.data.delivery.id = response["delivery_people"];
            }
            this.$refs.stepper.next();
          }
        })
        .catch((e) => {
          if (form.hasCallback) {
            form.hasCallback();
          }
          if (e && e.response && e.response.error) {
            this.notifyError(this.$t(e.response.error));
          } else if (e && e.message) {
            this.notifyError(e.message);
          } else {
            this.notifyError(
              "Não foi possivel finalizar o checkout, verifique se você tem permissão ou tente novamente mais tarde."
            );
          }
        });
    },
    savePaymentType(form) {
      let payload = {
        id: this.order.id,
        values: {
          paymentType: this.data.summary.paymentType,
        },
      };

      if (this.myCompany !== null)
        payload.query = {
          myCompany: this.myCompany.id,
        };

      this.choose_payment_quote(payload)
        .then((response) => {
          if (response["@id"]) {
            this.$emit("finished", payload);
          } else {
            if (form.hasCallback) {
              form.hasCallback();
            }
            if (response && response.response && response.response.error) {
              this.notifyError(this.$t(response.response.error));
            } else {
              this.notifyError(
                "Não foi possivel finalizar o checkout, verifique se a forma de pagamento foi escolhida."
              );
            }
          }
        })
        .catch((e) => {
          if (form.hasCallback) {
            form.hasCallback();
          }
          if (response && response.response && response.response.error) {
            this.notifyError(this.$t(response.response.error));
          } else {
            this.notifyError(
              "Não foi possivel finalizar o checkout, verifique se você tem permissão ou tente novamente mais tarde."
            );
          }
        });
    },
    savePayer(form) {
      const selectedQuoteId = this.lockedQuoteId || this.syncSelectedQuoteId();

      let payload = {
        id: this.order.id,
        values: {
          quote: selectedQuoteId,
          payer: this.data.summary.payer,
          payerDocument: this.data.summary.peopleDocument,
          comments: this.data.summary.comments,
        },
      };

      if (this.myCompany !== null)
        payload.query = {
          myCompany: this.myCompany.id,
        };

      this.choose_payer_quote(payload)
        .then((response) => {
          if (response["@id"]) {
            this.$emit("finished", payload);
          } else {
            if (form.hasCallback) {
              form.hasCallback();
            }

            if (response && response.response && response.response.error) {
              this.notifyError(this.$t(response.response.error));
            } else {
              this.notifyError(
                "Não foi possivel finalizar o checkout, verifique se você tem permissão ou tente novamente mais tarde."
              );
            }
          }
        })
        .catch((e) => {
          if (form.hasCallback) {
            form.hasCallback();
          }

          if (e && e.response && e.response.error) {
            this.notifyError(this.$t(e.response.error));
          } else if (e && e.message) {
            this.notifyError(e.message);
          } else {
            this.notifyError(
              "Não foi possivel finalizar o checkout, verifique se você tem permissão ou tente novamente mais tarde."
            );
          }
        });
    },

    notifyError(message) {
      this.$q.notify({
        message: message,
        position: "bottom",
        type: "negative",
      });
    },
  },
};
</script>

<style lang="stylus" scoped>

</style>
