<template>
    <Form
        ref="theForm"
        v-slot="{ meta }"
        @submit="onSubmit"
        @invalidSubmit="onInvalidSubmit">
        <div class="container-fluid fade-on-route-transition">
            <div class="row justify-content-center">
                <div class="col-md-6 px-0 px-md-2">
                    <siteHeader
                        ref="siteHeader"
                        cmsWidgetName="SiteHeaderWidget" />
                </div>
            </div>
            <div class="row justify-content-center pt-5">
                <div class="col-md-6 col-xl-4">
                    <h5
                        ref="siteSubHeader"
                        class="text-center text-black"
                        v-html="coverageStatementSubHeader"></h5>
                    <div
                        ref="explanatoryText"
                        class="body-text text-center mt-2"
                        v-html="explanatoryText"></div>
                    <div
                        ref="secondaryText"
                        class="text-center mt-4 mb-1 fw-bold text-black"
                        v-html="secondaryText"></div>
                    <div
                        v-if="isDeductibleVisible"
                        class="d-flex justify-content-center cost">
                        {{ formatAmountInDollars(deductibleValue) }}
                    </div>
                    <div
                        v-if="isQuoteDisplayed"
                        class="d-flex justify-content-center cost mb-0">
                        {{ formatAmountInDollars(totalServicePrice) }}
                    </div>
                    <div
                        v-if="isITACQuoteVisible"
                        class="d-flex justify-content-center mb-4 deductible-text">
                        {{ deductibleText }}&nbsp;
                        <span class="text-success fw-bold">{{
                            formatAmountInDollars(deductibleValue)
                        }}</span>
                    </div>
                    <alert
                        v-if="isITACQuoteVisible"
                        ref="verifiedITACAlert"
                        class="mb-5"
                        cmsWidgetName="VerifiedITACAlert"
                        :manualHeadline="verifiedItacAlertHeader"
                        :manualCopy="verifiedItacAlertBody"
                        alertClass="alert-success"
                        :isDismissible="false">
                    </alert>
                    <div
                        class="fw-bold text-black mt-5 mb-2"
                        v-html="nextStepsHeader"></div>
                    <div
                        class="body-text"
                        v-html="nextStepsBody"></div>
                    <buttonQuestion
                        v-if="isQuoteDisplayed"
                        v-model="selectedProvider"
                        cmsWidgetName="ServiceProviderQuestion"
                        :questionText="serviceProviderQuestionText"
                        :answers="serviceProviderQuestionAnswers"
                        groupName="ServiceProviderQuestionOption"
                        buttonTypeString="listButton"
                        isRequired
                        :validationRules="rules.selectionRequired">
                    </buttonQuestion>
                    <text-block
                        v-if="isQuoteDisplayed"
                        cmsWidgetName="DisclaimerWidget"
                        typeStyle="caption" />
                    <siteFooter
                        ref="siteFooter"
                        class="mt-5"
                        cmsWidgetName="SiteFooterWidget"
                        :isForwardActionDisabled="!meta.valid"
                        @backClicked="navigateBackByVehicleQuestions"
                        @forwardClicked="navigateForward" />
                </div>
            </div>
        </div>
        <recalModal
            ref="RecalModal"
            cmsWidgetName="RecalModal"
            class="recal-modal" />
        <contentGroupModal
            ref="DeductibleModal"
            cmsWidgetName="DeductibleModal"
            class="deductible-modal" />
    </Form>
</template>
<script>
// Import Component
import { Form } from 'vee-validate';
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
import siteHeader from '@/iss-components/site-header/site-header.vue';
import recalModal from '@/layouts/coverage-statement/recal-modal/recal-modal.vue';
import alert from '@/ux-components/alert/alert.vue';
import contentGroupModal from '@/iss-components/content-group-modal/content-group-modal.vue';
import buttonQuestion from '@/digital-components/button-question/button-question.vue';
import textBlock from '@/digital-components/text-block/text-block.vue';

// Import Supporting Files
import {
    fetchCmsContentForPage,
    setupModalLinks,
    processIfStatements
} from '@/helpers/cms-content-helper.js';
import settleAllPromises from '@/helpers/layout-helper.js';
import { getDamageString } from '@/helpers/damage-helper.js';
import { useMainStore } from '@/store/index.js';
import vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin.js';
import globalRules from '@/constants/global-rules.js';
import baseFormMixin from '@/mixins/base-form-mixin.js';
import navigationScenarios from '@/router/router-constants/navigation-scenarios.js';
import bailoutMessage from '@/constants/bailoutMessage';
import widgetFields from '@/constants/cms-widget-fields.js';
import { formatAmountInDollars } from '@/helpers/text-helper.js';
import showIssLoadingModal from '@/helpers/loading-modal-helper';
import { getPriceOfLineItems } from '@/helpers/price-calculator';
import coverageStatuses from '@/constants/coverage-statuses';
import coverageType from '@/constants/coverage-type';

const SAFELITE_PROVIDER = 'Safelite';

export default {
    name: 'coverage-statement',
    components: {
        siteFooter,
        siteHeader,
        // eslint-disable-next-line vue/no-reserved-component-names
        Form,
        recalModal,
        alert,
        contentGroupModal,
        buttonQuestion,
        textBlock
    },
    mixins: [baseFormMixin, vehicleQuestionsMixin],
    async beforeRouteEnter(to, from, next) {
        const store = useMainStore();

        // Call APIs
        const cmsContentPromise = fetchCmsContentForPage(to?.query?.issPage);
        const supportingItemsPromise = store.getSupportingItems();

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

        const { vehicle, isITAC, isDeductible, serviceLocation } = store;
        if ((isITAC || isDeductible)
            && vehicle.policyVehicleId >= 0) {
            promiseResultMap.push({
                resultKey: 'getFinalDeductible',
                promise: store.getFinalDeductible()
            });
        }

        if (!serviceLocation.zipCodeCtu) {
            promiseResultMap.push({
                resultKey: 'validateZip',
                promise: store.validateZip({ zip: store.order.policy.policyZipCode })
            });
        }

        const resultMap = await settleAllPromises(promiseResultMap);

        next(async (vm) => {
            showIssLoadingModal(true);
            vm.setCmsContent(resultMap.cmsContent);
            vm.setSupportingItems(resultMap.supportingItems);
            await vm.initializeComponent();
            if (!vm.unverified) {
                useMainStore().disableKeyFields();
            }
        });
    },
    setup() {
        const mainStore = useMainStore();
        return { mainStore };
    },
    data() {
        return {
            baseServiceLineItems: [],
            selectedProvider: '',
            deductibleText: 'Your deductible is',
            // TODO update when design team gives appropriate text
            rules: {
                selectionRequired: globalRules.OPTION_REQUIRED
            },
            widget: {
                subheader: 'SiteSubHeaderWidget',
                verifiedItacAlert: 'VerifiedITACAlert',
                explanatoryText: 'ExplanatoryTextWidget',
                nextStep: 'NextStepsWidget',
                serviceProviderQuestion: 'ServiceProviderQuestion'
            }
        };
    },
    computed: {
        coverageStatementSubHeader() {
            return this.getTextFromCmsWithCustomIfStatements(
                this.widget.subheader,
                widgetFields.SUB_HEADER_WIDGET.SUB_HEADER_TEXT
            );
        },
        verifiedItacAlertHeader() {
            return this.getCmsContent(
                this.widget.verifiedItacAlert,
                widgetFields.ALERT_WIDGET.HEADLINE_TEXT
            );
        },
        verifiedItacAlertBody() {
            const itacCostSavings =
                this.deductibleValue - this.totalServicePrice;
            return this.getCmsContent(
                this.widget.verifiedItacAlert,
                widgetFields.ALERT_WIDGET.BODY_TEXT
            )?.replaceAll(
                '{custom:costSavings}',

                formatAmountInDollars(itacCostSavings)
            );
        },
        secondaryText() {
            return this.getTextFromCmsWithCustomIfStatements(
                this.widget.subheader,
                widgetFields.SUB_HEADER_WIDGET.SECONDARY_TEXT
            );
        },
        explanatoryText() {
            return this.getTextFromCmsWithCustomIfStatements(
                this.widget.explanatoryText,
                widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT
            );
        },
        nextStepsHeader() {
            return this.getTextFromCmsWithCustomIfStatements(
                this.widget.nextStep,
                widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT
            );
        },
        nextStepsBody() {
            return this.getTextFromCmsWithCustomIfStatements(
                this.widget.nextStep,
                widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT
            )?.replaceAll('{custom:damage}', this.damageText);
        },
        damageText() {
            const damageString = getDamageString();
            return damageString === 'match' ? '' : damageString;
        },
        deductibleValue() {
            return useMainStore().order.currentDeductible;
        },
        isNoCompQuoteVisible() {
            return this.mainStore.isVerified && this.mainStore.isNoComp;
        },
        isITACQuoteVisible() {
            return this.mainStore.isVerified && this.mainStore.isITAC;
        },
        isDeductibleVisible() {
            return this.mainStore.isVerified && this.mainStore.isDeductible;
        },
        isUnverifiedVisible() {
            return this.mainStore.isUnverified;
        },
        isADAS() {
            const { glassParts } = useMainStore().order.lineItems;
            return (
                glassParts !== null
                && !!glassParts.find((part) => part.requiresRecalibration)
            );
        },
        totalServicePrice() {
            return getPriceOfLineItems(this.baseServiceLineItems);
        },
        serviceProviderQuestionText() {
            return this.getCmsContent(
                this.widget.serviceProviderQuestion,
                widgetFields.INPUT_QUESTION_WIDGET.QUESTION_TEXT
            );
        },
        serviceProviderQuestionAnswers() {
            return this.getCmsContent(
                this.widget.serviceProviderQuestion,
                widgetFields.INPUT_QUESTION_WIDGET.ANSWERS
            );
        },
        isQuoteDisplayed() {
            return this.isITACQuoteVisible || this.isNoCompQuoteVisible;
        },
        shouldRegisterClaim() {
            const {
                vehicle,
                isClaimRegistrationRequired,
                isPolicyLookupSuccessful,
                isPendingClaimRegistration
            } = useMainStore();
            const { policyVehicleId } = vehicle;
            return (
                isPolicyLookupSuccessful
                && policyVehicleId != null
                && policyVehicleId >= 0
                && isClaimRegistrationRequired
                && isPendingClaimRegistration
            );
        },
        isRepair() {
            return this.mainStore.order.damage.isRepair;
        }
    },
    watch: {
        selectedProvider() {
            const buttonText =
                this.selectedProvider === SAFELITE_PROVIDER
                    ? 'Continue with Safelite'
                    : 'Continue';
            this.$refs.siteFooter.updateButtonText(buttonText);
        },
        nextStepsBody(newValue, oldValue) {
            if (newValue !== oldValue) {
                setupModalLinks(this, 'RecalModal');
                setupModalLinks(this, 'DeductibleModal');
            }
        }
    },
    mounted() {
        setupModalLinks(this);
    },
    methods: {
        arePagePrerequisitesValid() {
            return !!useMainStore().vehicle.carId;
        },
        async initializeComponent() {
            if (this.shouldRegisterClaim) {
                await this.mainStore.registerClaim();
            } else if (!this.mainStore.isClaimRegistrationRequired) {
                this.mainStore.updateCoverageStatus(coverageStatuses.VERIFIED);
            }

            if (this.mainStore.isVerified) {
                await this.getPricedParts();

                // Repairs will never be ITAC
                if (this.isRepair && this.mainStore.isITAC) {
                    this.mainStore.updateCoverageType(coverageType.Deductible);
                }
            }

            showIssLoadingModal(false);
        },
        async getPricedParts() {
            const clonedGlassParts = useMainStore().lineItems.glassParts
                ? JSON.parse(JSON.stringify(useMainStore().lineItems.glassParts))
                : [];
            const availableLineItems = [
                ...(this.mainStore.lineItems.supportingItems ?? []),
                ...(clonedGlassParts ?? [])
            ];

            // We only call the ITAC pricing endpoint if we are not repair or we are NoComp
            if (!this.isRepair || this.mainStore.isNoComp) {
                const pricingResults = await useMainStore().getITACPriceOrderItems(availableLineItems)
                    .catch((err) => {
                        useMainStore().setBailout(bailoutMessage.pricingResponseError(
                            availableLineItems.map((li) => li.partNumber),
                            {
                                code: err.code,
                                message: err.message,
                                data: err.data
                            }
                        ));
                        this.navigateWithScenario(navigationScenarios.PRICING_LOOKUP_ERROR);
                    });
                this.setBaseServiceLineItems(pricingResults);
            }
        },
        async navigateForward() {
            if (this.isUnverifiedVisible || this.isDeductibleVisible) {
                this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD);
            } else if (this.isITACQuoteVisible || this.isNoCompQuoteVisible) {
                useMainStore().updateIsSafeliteProvider(this.selectedProvider === SAFELITE_PROVIDER);
                if (this.selectedProvider === SAFELITE_PROVIDER) {
                    this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE);
                } else {
                    useMainStore().setBailout(bailoutMessage.RequestCallback());
                    this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP);
                }
            } else {
                useMainStore().setBailout(bailoutMessage.coverageStatementInvalidState());
                this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD_WITH_INVALID_STATE);
            }
        },
        navigateWithScenario(scenario) {
            this.$router.navigate(scenario, this.$route);
        },
        getTextFromCmsWithCustomIfStatements(widgetName, widgetField) {
            const rawText = this.getCmsContent(widgetName, widgetField);
            return processIfStatements(
                rawText,
                'custom',
                this.getCustomValueFromString
            );
        },
        getCustomValueFromString(str) {
            const { isRepair } = useMainStore().damage;
            switch (str) {
                case 'coverageUnverified':
                    return this.isUnverifiedVisible;
                case 'verifiedDeductible':
                    return this.isDeductibleVisible;
                case 'verifiedITAC':
                    return this.isITACQuoteVisible;
                case 'verifiedNoComp':
                    return this.isNoCompQuoteVisible;
                case 'ADASReplace':
                    return !isRepair && this.isADAS;
                case 'nonADASReplace':
                    return !isRepair && !this.isADAS;
                case 'nonADASRepair':
                    return isRepair;
                case 'deductibleOverZero':
                    return (
                        this.isDeductibleVisible && this.deductibleValue !== 0
                    ); // TODO what if deductible is negative?
                case 'isDeductibleZero':
                    return (
                        this.isDeductibleVisible && this.deductibleValue === 0
                    );
                default:
                    return null;
            }
        },
        setSupportingItems(newSupportingItems) {
            this.mainStore.updateSupportingItems(newSupportingItems);
        },
        setBaseServiceLineItems(lineItems) {
            this.baseServiceLineItems = lineItems;
        },
        formatAmountInDollars
    }
};
</script>

<style lang="scss" scoped>
.cost {
    color: $green;
    font-size: 2rem;
    font-weight: $font-weight-light;
    line-height: 2.75rem;
}

.deductible-text {
    line-height: 1.5rem;
}

:deep p {
    line-height: 1.5rem;
    font-size: 0.875rem;
    margin-bottom: 0.5rem;
    strong {
        color: $black;
    }
}

:deep .question-text {
    margin-top: 1.5rem;
    margin-bottom: 0.5rem;
    font-size: 1rem;
    line-height: 1.5rem;
    & > span {
        text-align: left;
    }
}

:deep .deductible-modal {
    p {
        margin-bottom: 0 !important;
        font-size: 1rem;
        line-height: 1.625rem;
    }
    img.mb-4 {
        margin: 0 !important;
    }
    h5 {
        color: black;
    }
    p:last-child {
        margin-top: 0.5rem;
    }
}

:deep(.recal-modal) {
    p {
        font-size: 1rem;
        line-height: 1.625rem;

        &.modal-body {
            padding: 0;
        }
    }
}

.modal {
    overflow: hidden;
}
</style>
