<template>
    <Form
        ref="theForm"
        v-slot="{ meta }"
        @submit="onSubmit"
        @invalidSubmit="onInvalidSubmit">
        <div class="page-container-grouped-styles">
            <div class="fade-on-route-transition position-relative">
                <siteHeader cmsWidgetName="SiteHeaderWidget" />
                <div class="container-fluid pb-2 payment">
                    <div id="card-container">
                        <iframe
                            id="card-frame"
                            ref="paymentFrame"
                            v-resize
                            class="hop-iframe payment-iframe"
                            name="card-frame"
                            seamless
                            scrolling="no">
                        </iframe>
                    </div>

                    <siteFooter
                    ref="siteFooter"
                    cmsWidgetName="SiteFooterWidget"
                    :isForwardActionDisabled="true"
                    isForwardButtonHidden="true"
                    @ForwardClicked="forwardButtonAction"
                    @backClicked="backButtonAction" />
                </div>
            </div>

            <div
                v-if="shouldBlockInteraction"
                class="ui-block"
                @click="supressClick"></div>
        </div>
    </Form>

    <form
        ref="hopForm"
        id="card-data"
        :target="isPaypal ? '_top' : 'card-frame'"
        method="POST"
        :action="checkoutUrl">
        <input type="hidden" name="paymentType" :value="paymentType" />
        <input type="hidden" name="sgSessionId" :value="authToken" />
        <input type="hidden" name="sgAuthToken" :value="authToken" />
        <input type="hidden" name="sgSignaturePublic" :value="authSignature" />
        <input type="hidden" name="sgSignatureStartDate" :value="authSignatureStart" />
        <input type="hidden" name="referralSeqNum" :value="referralSequenceNumber" />

        <input type="hidden" name="sge_commerce_indicator_isinternet" value="true" />
        <input type="hidden" name="sghopsource" value="Safelite.com" />
        <input type="hidden" name="sgHtmlStyle" value="ResourceSafeliteHtml" />
        <input type="hidden" name="sgErrorMessagesEmbedded" value="true" />

        <input type="hidden" name="sgNoKeystrokeProcessing" value="false" />

        <input type="hidden" name="maskCharacter" value="*" />
        <input type="hidden" name="styleSheetCode" :value="dynamicCSSUrl" />
        <input type="hidden" name="styleSheetCode2" :value="dynamicHopCSSUrl" />

        <input type="hidden" name="sgReceiptResponseURL" :value="payInAdvanceResponseUrl" />
        <input type="hidden" name="sgDeclineResponseURL" :value="payInAdvanceResponseUrl" />
        <input type="hidden" name="sgErrorResponseURL" :value="payInAdvanceResponseUrl" />

        <input type="hidden" name="sgheaderline1" :value="getHeaderLine1" />
        <input type="hidden" name="sgHeader1subtitle" value="" />
        <input type="hidden" name="sgheaderline2" :value="getHeaderLine2" />
        <input type="hidden" name="sgheaderline3" value="" />
        <input type="hidden" name="sgheaderline4" value="" />
        <input type="hidden" name="sgheaderline5" value="*Required information" />

        <input type="hidden" name="billTo_firstName" :value="firstName" />
        <input type="hidden" name="billTo_firstNameShow" value="true" />
        <input type="hidden" name="sghopmiddleInitialShow" value="false" />
        <input type="hidden" name="billTo_lastName" :value="lastName" />
        <input type="hidden" name="billTo_lastNameShow" value="true" />

        <input type="hidden" name="billTo_street1" value="" />
        <input type="hidden" name="billTo_street2" value="" />
        <input type="hidden" name="billTo_city" value="" />
        <input type="hidden" name="billTo_state" value="" />

        <input type="hidden" name="billTo_postalCode" value="" />
        <input type="hidden" name="billTo_postalCodeShow" value="true" />
        <input type="hidden" name="billTo_postalCodeEnable" value="true" />
        <input type="hidden" name="sgLabelPostalCode" value="Billing ZIP" />

        <input type="hidden" name="sgtotalamount" :value="displayAmount" />
        <input type="hidden" name="totalAmountDecimal" :value="totalAmount" />
        <input type="hidden" name="lineItems" :value="payInAdvanceLineItems" />

        <input type="hidden" name="sgdiscountstrikethruamount" value="" />

        <input type="hidden" name="callerDisplayText" value="" />

        <input
            type="hidden"
            name="sgtermsofusedisplaytext"
            value="By selecting submit, I agree to Safelite's" />
        <input type="hidden" name="sgtermsofuseurl" value="http://www.safelite.com/terms-of-use/" />
        <input type="hidden" name="sgtermsofuselinkdisplaytext" value="terms of use" />
        <input type="hidden" name="sgtermsofcancelrefunddisplaytext" value="and" />
        <input
            type="hidden"
            name="sgtermsofcancelrefundlinkdisplaytext"
            value="cancellation and refund policy" />
        <input
            type="hidden"
            name="sgtermsofcancelrefundurl"
            value="http://www.safelite.com/cancellation-refund-policy" />

        <input
            type="hidden"
            name="sgErrorMessageCardVerification"
            value="Credit card could not be processed" />
        <input
            type="hidden"
            name="sgErrorMessageTimeOut"
            value="For your security, this transaction has been timed out." />

        <input type="hidden" name="sgLabelCardNumber" value="" />
        <input type="hidden" name="sgLabelAddressLine1" :value="address1" />
        <input type="hidden" name="sgLabelAddressLine2" :value="address2" />
        <input type="hidden" name="sgLabelCity" :value="city" />
        <input type="hidden" name="sgLabelState" :value="state" />

        <input type="hidden" name="sgCtu" :value="ctu" />
        <input type="hidden" name="sgWorkOrder" :value="workOrderNumber" />
        <input type="hidden" name="sgEmailAddress" :value="emailAddress" />
        <input type="hidden" name="paypalInvoiceNumber" :value="invoiceNumber" />
        <input type="hidden" name="paypalSuccessUrl" :value="payInAdvanceResponseUrl" />
        <input type="hidden" name="paypalCancelUrl" :value="payInAdvanceCancelUrl" />

        <input type="hidden" name="sgCCDeclineURL" :value="payInAdvanceCancelUrl" />
        <input type="hidden" name="sgCCTimeoutURL" :value="payInAdvanceCancelUrl" />

        <input type="hidden" name="sgTransactionType" value="authorization" />
        <input type="hidden" name="amount" :value="totalAmount" />
        <input type="hidden" name="ctu" :value="ctu" />
        <input type="hidden" name="orderNumber" :value="workOrderNumber" />

        <input type="hidden" name="billTo_email" :value="emailAddress" />
        <input type="hidden" name="useDecisionManager" value="True" />
        <input type="hidden" name="correlationId" :value="referralCorrelationId" />
        <input type="hidden" name="sgErrorMessageCard_CVN" value="Please enter a valid CVV" />

        <input type="hidden" name="ship_to_address_line1" :value="address1" />
        <input type="hidden" name="ship_to_address_line2" :value="address2" />
        <input type="hidden" name="ship_to_address_city" :value="city" />
        <input type="hidden" name="ship_to_address_state" :value="state" />
        <input type="hidden" name="ship_to_address_country" value="US" />
        <input type="hidden" name="ship_to_address_postal_code" :value="zipCode" />
        <input type="hidden" name="ship_to_phone" :value="phoneNumber" />

        <input type="hidden" name="calling_application" value="NextGen" />
    </form>
</template>
<script>
// Components
import siteHeader from '@/iss-components/site-header/site-header.vue';
import siteFooter from '@/iss-components/site-footer/site-footer.vue';

// Supporting files
import applicationConfig from '@/constants/application-config.js';
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import settleAllPromises from '@/helpers/layout-helper';
import { Form } from 'vee-validate';
import BaseFormMixin from '@/mixins/base-form-mixin.js';
import { useMainStore } from '@/store';
import iframeResize from '../../../node_modules/iframe-resizer/js/iframeResizer.js';
import externalUrls from '@/router/router-constants/externalUrl-values.js';
import widgetFields from '@/constants/cms-widget-fields.js';
import paymentMethods from '@/constants/payment-method-constants';
import { AppointmentTypeStrings } from '@/constants/schedule-constants';

export default {
    name: 'payment-page',
    components: {
        siteHeader,
        siteFooter,
        // eslint-disable-next-line vue/no-reserved-component-names
        Form
    },
    directives: {
        resize: {
            mounted(el) {
                el.addEventListener('load', () => {
                    iframeResize({ checkOrigin: false }, el);
                });
            },
            unmounted(el) {
                el.iFrameResizer.removeListeners();
            }
        }
    },
    mixins: [BaseFormMixin],
    async beforeRouteEnter(to, from, next) {
        // Call APIs
        const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);

        const paymentSignaturePromise = await useMainStore().getPaymentSignature();

        // Settle promises and get results
        const promiseResultMap = [
            {
                resultKey: 'cmsContent',
                promise: cmsContentPromise
            },
            {
                resultKey: 'paymentSignature',
                promise: paymentSignaturePromise
            }
        ];

        // use resultMap to populate layout content.
        const resultMap = await settleAllPromises(promiseResultMap);

        next((vm) => {
            vm.setCmsContent(resultMap.cmsContent);

            vm.$nextTick(() => {
                vm.fetchSignatureInfo(resultMap.paymentSignature);
                vm.setIFrameListener();
            });
        });
    },
    setup() {
        const mainStore = useMainStore();
        return { mainStore };
    },
    data() {
        return {
            checkoutUrl: externalUrls.SAFELITE_HOP,
            payInAdvanceResponseUrl: applicationConfig.PAY_IN_ADVANCE_RESPONSE_URL,
            payInAdvanceCancelUrl: applicationConfig.PAY_IN_ADVANCE_CANCEL_URL,
            paymentType: this.getPaymentType(),
            authToken: '',
            authSignature: '',
            authSignatureStart: '',
            referralSequenceNumber: useMainStore().order.referralSequenceNumber,
            emailAddress: useMainStore().order.customer.emailAddress,
            address1: this.getAddress1(),
            address2: this.getAddress2(),
            city: this.getCity(),
            state: this.getState(),
            zipCode: this.getZipCode(),
            firstName: useMainStore().order.customer.firstName,
            lastName: useMainStore().order.customer.lastName,
            phoneNumber: useMainStore().order.customer.phoneNumber,
            ctu: useMainStore().order.serviceLocation.zipCodeCtu,
            referralCorrelationId: useMainStore().order.referralCorrelationId,
            workOrderNumber: this.getWorkOrderNumber(),
            invoiceNumber: this.getInvoiceNumber(),
            totalAmount: this.getAmountDue(),
            displayAmount: this.getDisplayAmountDue(),
            payInAdvanceLineItems: '',
            shouldBlockInteraction: false
        };
    },
    computed: {
        dynamicCSSUrl() {
            const { protocol, hostname, port } = window.location;
            return `${protocol}//${hostname}:${port}/css/site-2020Styling.css`;
        },
        dynamicHopCSSUrl() {
            const { protocol, hostname, port } = window.location;
            return `${protocol}//${hostname}:${port}/css/hop-styling.css`;
        },
        getHeaderLine1() {
            if (!this.isPaypal) {
                return this.getCmsContent('PayInAdvanceHeaderLine1', widgetFields.TEXT_BLOCK_WIDGET.TEXT);
            }
            return '';
        },
        getHeaderLine2() {
            if (!this.isPaypal) {
                return this.getCmsContent('PayInAdvanceHeaderLine2', widgetFields.TEXT_BLOCK_WIDGET.TEXT);
            }
            return '';
        },
        isPaypal() {
            if (this.paymentType === 'pp') {
                return true;
            }
            return false;
        }
    },
    methods:
    {
        arePagePrerequisitesValid() {
            // Line Items
            const packageReqs = !!useMainStore().order.lineItems.supportingItems;

            // Service Location
            const { serviceLocation } = useMainStore().order;
            const mobileReqs = !!(
                serviceLocation.address
                && serviceLocation.city
                && serviceLocation.state
                && serviceLocation.zipCode
            );

            const providerLocation = serviceLocation.provider.address;
            const dropOffInshopReqs = !!(
                providerLocation.streetAddress
                && providerLocation.city
                && providerLocation.state
                && providerLocation.zipCode
            );

            const isMobile = serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE;

            const serviceLocationReqs =
                (isMobile && mobileReqs) || (!isMobile && dropOffInshopReqs);

            // Insurance
            const isInsuranceSet = useMainStore().order.payment.isInsurance !== null;

            // Schedule
            const { schedule } = useMainStore().order;
            const scheduleReqs = !!(
                schedule.date
                && schedule.startTime
                && schedule.endTime
                && schedule.jobMaxMinutes
                && schedule.jobMinMinutes
            );

            // Customer
            const { customer } = useMainStore().order;
            const customerReqs = !!(
                customer.firstName
                && customer.lastName
                && customer.phoneNumber
                && customer.emailAddress
            );

            const paymentMethodReqs =
                useMainStore().order.payment.isPayInAdvance !== null
                && (useMainStore().order.payment.isPayInAdvance || !!useMainStore().order.payment.payInAdvanceType);

            return (
                packageReqs
                && serviceLocationReqs
                && isInsuranceSet
                && scheduleReqs
                && customerReqs
                && paymentMethodReqs
            );
        },
        getWorkOrderNumber() {
            const { workOrderNumber } = useMainStore().order;
            if (workOrderNumber) {
                const items = workOrderNumber.split('-');
                if (items.length > 1) {
                    return items[1];
                }
            }
            //this.backButtonAction();
            return undefined;
        },
        getInvoiceNumber() {
            const { workOrderNumber } = useMainStore().order;
            if (workOrderNumber) {
                return workOrderNumber.replace('-', '');
            }
            //this.backButtonAction();
            return undefined;
        },
        getAddress1() {
            return useMainStore().order.serviceLocation.address
                ? useMainStore().order.serviceLocation.address
                : useMainStore().order.serviceLocation.provider.address.streetAddress;
        },
        getAddress2() {
            return useMainStore().order.serviceLocation.address2
                ? useMainStore().order.serviceLocation.address2
                : null;
        },
        getCity() {
            return useMainStore().order.serviceLocation.city
                ? useMainStore().order.serviceLocation.city
                : useMainStore().order.serviceLocation.provider.address.city;
        },
        getState() {
            return useMainStore().order.serviceLocation.state
                ? useMainStore().order.serviceLocation.state
                : useMainStore().order.serviceLocation.provider.address.state;
        },
        getZipCode() {
            return useMainStore().order.serviceLocation.zipCode
                ? useMainStore().order.serviceLocation.zipCode
                : useMainStore().order.serviceLocation.provider.address.zipCode;
        },
        getPaymentType() {
            switch (useMainStore().order.payment.payInAdvanceType) {
                case paymentMethods.AFTERPAY:
                    return 'ap';
                case paymentMethods.CREDIT_CARD:
                    return 'cc';
                case paymentMethods.PAYPAL:
                    return 'pp';
                default:
                    return useMainStore().payment.payInAdvanceType;
            }
        },
        getAmountDue() {
            return 0;
        },
        getDisplayAmountDue() {
            return 0;
        },
        fetchSignatureInfo(signatureInfo) {
            this.authToken = signatureInfo.token;
            this.authSignature = signatureInfo.signature;
            this.authSignatureStart = signatureInfo.startDate;

            this.submitHopForm();
        },
        submitHopForm() {
            this.$nextTick(() => {
                this.$refs.hopForm.submit();

                const iframe = this.$refs.paymentFrame;
                if (iframe) {
                    iframe.onload = () => {
                        if (iframe.contentWindow) {
                            if (this.paymentType === 'cc') {
                                iframe.contentWindow.postMessage('CreditCardChosen', '*');
                            } else if (this.paymentType === 'ap') {
                                iframe.contentWindow.postMessage('afterpay', '*');
                            }
                        }
                    };
                }
            });
        },
        handleIFrameContentWindowMessage(event) {
            if (typeof event.data === 'string') {
                if (event.data.indexOf('afterpayClosed') > -1) {
                    this.backButtonAction();
                }
                if (event.data.indexOf('creditCardSubmit') > -1) {
                    this.setUIBlock(true);
                }
            }
        },
        setIFrameListener() {
            window.addEventListener('message', (event) =>
                this.handleIFrameContentWindowMessage(event));
        },
        setUIBlock(val) {
            this.shouldBlockInteraction = val;
        },
        supressClick(event) {
            if (this.shouldBlockInteraction) {
                event.stopPropagation();
            }
        },
        backButtonAction() {
            // page will not render with normal navigation due to navigating from the iframe
            window.location = this.payInAdvanceCancelUrl;
        },
        forwardButtonAction() {
            this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$route);
        },
        navigateForward() {
        }
    }
};
</script>
<style lang="scss" scoped>
.payment p{
    margin-bottom:0.75rem;
}

.hop-iframe {
    position: relative;
    min-height: 40.625rem;
    width: 100%;
    border: 0 none;
}

.ui-block {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 9999;
}
</style>
