<template>
    <Form
        ref="theForm"
        @submit="onSubmit"
        @invalidSubmit="onInvalidSubmit">
    </Form>
</template>

<script>
import { Form } from 'vee-validate';
import BaseFormMixin from '@/mixins/base-form-mixin.js';
import { useMainStore } from '@/store/index.js';
import queryStrings from '@/constants/query-strings';
import { getCartTotal } from '@/helpers/cart-helper';
import { submitWorkOrder } from '@/helpers/order-helper.js';
import { createAdyenCheckout, generateCcToken, getSessionInfo, mapAdyenToIssPaymentMethod } from '@/helpers/adyen-helper';
import navigationScenarios from '@/router/router-constants/navigation-scenarios';
import submitType from '@/constants/submit-type';
import showIssLoadingModal from '@/helpers/loading-modal-helper';
import { paymentMethods } from '@/constants/payment-method-constants';

export default {
    name: 'payment-return-adyen',
    components: {
        Form
    },
    mixins: [BaseFormMixin],
    async mounted() {
        showIssLoadingModal(true);
        const store = useMainStore();

        const sessionId = this.$route?.query?.sessionId;
        const redirectResult = this.$route?.query?.redirectResult;

        if (sessionId && redirectResult) {
            let result = null;

            try {
                result = await this.finalizeAdyenPayment(sessionId, redirectResult);
            } catch (unexpectedResult) {
                // If user cancelled payment, handle without error message
                if (unexpectedResult.code === "Cancelled" || unexpectedResult.code === "CANCEL") {
                    this.$router.navigate(navigationScenarios.PAY_IN_ADVANCE_CANCEL, this.$route);
                    return;
                }

                // Otherwise, failure scenario.
                // Payment fails, so return user to payment-page-adyen screen to try again or pay later.
                this.$router.navigate(
                    navigationScenarios.PAY_IN_ADVANCE_ERROR,
                    this.$route,
                    {
                        [queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT]: true
                    }
                );
                return;
            }
            const sessionInfo = await getSessionInfo(sessionId, result.sessionResult);

            const paymentMethod = mapAdyenToIssPaymentMethod(sessionInfo?.paymentMethod);
            const amountDue = getCartTotal(store.order);
            const ccToken = generateCcToken(sessionInfo);
            if (paymentMethod === paymentMethods.AFTERPAY) {
                ccToken.authCode = "831001";
                ccToken.cardType = "VS";
                ccToken.lastFour = "1111";
                ccToken.expMonth = "03";
                ccToken.expYear = "2030";
            }

            store.savePaymentMethodChoice(paymentMethod);
            store.updateCreditCardToken(ccToken);
            store.updateNextGenSettledAmount(amountDue);
            store.clearSaveSessionPromise();

            try {
                await this.saveAndSubmitWorkOrder();
                return;
            } catch (error) {
                this.$router.navigate(
                    navigationScenarios.PAY_IN_ADVANCE_ERROR,
                    this.$route,
                    {
                        [queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT]: true
                    }
                );
            }
        }

        this.$router.navigate(
            navigationScenarios.PAY_IN_ADVANCE_ERROR,
            this.$route,
            {
                [queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT]: true
            }
        );
    },
    methods: {
        finalizeAdyenPayment(sessionId, redirectResult) {
            return new Promise((resolve, reject) => {
                createAdyenCheckout({
                    session: {
                        id: sessionId,
                    },
                    handlers: {
                        onPaymentCompleted: (result, component) => {
                            resolve(result);
                        },
                        onPaymentFailed: (result, component) => {
                            if (result?.resultCode !== "Cancelled") {
                                const stringToLog = `ADYEN PAYMENT NOT AUTHORIZED. Code = ${result?.resultCode}. Id = ${sessionId}`;

                                global.$logger.logError(stringToLog);
                            }

                            reject({
                                code: result?.resultCode,
                                message: "Payment failed from Adyen",
                            });
                        },
                        onError: (error, component) => {
                            if (error?.name !== "CANCEL") {
                                const stringToLog = `ADYEN ERROR. Name = ${error?.name}. Details = ${error?.message}.`;

                                global.$logger.logError(stringToLog);
                            }

                            reject({
                                code: error?.name,
                                message: "Error from Adyen",
                            });
                        },
                    },
                    options: {},
                }).then(
                    (checkout) => {
                        checkout.submitDetails({
                            details: {
                                redirectResult: redirectResult,
                            },
                        });
                    },
                    (error) => {
                        reject(error);
                    }
                );
            });
        },
        async saveAndSubmitWorkOrder() {
            // Final work order submit after returning from pay in advance.
            await submitWorkOrder({ submitType: submitType.SAFELITE });

            this.$router.navigate(
                this.navigationScenarios.PAY_IN_ADVANCE_SUCCESS,
                this.$route
            );
        }
    }
};
</script>
