<!-- eslint-disable vue/no-v-html -->
<template>
    <Form
        ref="theForm"
        v-slot="{ meta }"
        @submit="onSubmit"
        @invalidSubmit="onInvalidSubmit">
        <div class="fade-on-route-transition coverage-statement">
            <div class="justify-content-center">
                <siteHeader
                    ref="siteHeader"
                    cmsWidgetName="SiteHeaderWidget" />
            </div>
            <div class="iss-heritage-container-width">
                <div class="coverage-statement-container iss-heritage-content-container-width">
                    <h5
                        ref="siteSubHeader"
                        class="sub-header text-black mt-4"
                        v-html="coverageStatementSubHeader"></h5>
                    <div
                        ref="explanatoryText"
                        class="body-text mt-2"
                        v-html="explanatoryText"></div>
                    <div
                        ref="secondaryText"
                        class="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>
                    <siteFooter
                        :ref="SITE_FOOTER_REF_NAME"
                        class="mt-5"
                        cmsWidgetName="SiteFooterWidget"
                        :isForwardActionDisabled="!meta.valid"
                        @backClicked="navigateBackByVehicleQuestions"
                        @forwardClicked="navigateForward" />
                    <textBlock
                        v-if="isQuoteDisplayed"
                        :customText="disclaimerText"
                        typeStyle="caption" />
                </div>
            </div>
        </div>
        <contentGroupModal
            :ref="RECAL_MODAL_REF_NAME"
            cssModalHeadlineClass="text-center"
            cmsWidgetName="RecalModal" />
        <contentGroupModal
            :ref="DEDUCTIBLE_MODAL_REF_NAME"
            cmsWidgetName="DeductibleModal"
            class="deductible-modal" />
        <cancelClaimModal
            :ref="CANCEL_CLAIM_REF_NAME"
            @cancelClaimConfirmation="cancelClaim"
            @returnToClaim="continueClaim" />
    </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 alert from '@/ux-components/alert/alert.vue';
import cancelClaimModal from '@/layouts/coverage-statement/cancel-claim-modal/cancel-claim-modal.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,
    setupModalLink,
    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, createOrderedListFromStringOfParagraphs } 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 CANCEL_CLAIM_REF_NAME = 'CancelClaimModal';
const SAFELITE_PROVIDER = 'Safelite';
const RECAL_MODAL_REF_NAME = 'RecalModal';
const DEDUCTIBLE_MODAL_REF_NAME = 'DeductibleModal';
const SITE_FOOTER_REF_NAME = 'siteFooter';

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

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

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

        const { isITAC, isDeductible, serviceLocation } = store;
        if (isITAC || isDeductible) {
            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);
            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: {
                disclaimerText: 'DisclaimerWidget',
                subheader: 'SiteSubHeaderWidget',
                verifiedItacAlert: 'VerifiedITACAlert',
                explanatoryText: 'ExplanatoryTextWidget',
                nextStep: 'NextStepsWidget',
                serviceProviderQuestion: 'ServiceProviderQuestion'
            },
            CANCEL_CLAIM_REF_NAME,
            RECAL_MODAL_REF_NAME,
            DEDUCTIBLE_MODAL_REF_NAME,
            SITE_FOOTER_REF_NAME
        };
    },
    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
            );
        },
        disclaimerText() {
            return this.getTextFromCmsWithCustomIfStatements(
                this.widget.disclaimerText,
                widgetFields.TEXT_BLOCK_WIDGET.TEXT
            )?.replaceAll('{custom:disclaimerAmount}', formatAmountInDollars(this.totalServicePrice));
        },
        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() {
            const cmsText = this.getTextFromCmsWithCustomIfStatements(
                this.widget.nextStep,
                widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT
            )?.replaceAll('{custom:damage}', this.damageText);

            return createOrderedListFromStringOfParagraphs(cmsText);
        },
        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() {
            if (this.selectedProvider) {
                if (this.selectedProvider !== SAFELITE_PROVIDER) {
                    this.$refs[this.CANCEL_CLAIM_REF_NAME].openModal();
                    this.selectedProvider = '';
                    this.$refs.siteFooter.disableForwardButton();
                } else {
                    this.$refs.siteFooter.enableForwardAction();
                }
            }
        },
        nextStepsBody(newValue, oldValue) {
            if (newValue !== oldValue) {
                setupModalLink(this, RECAL_MODAL_REF_NAME);
                setupModalLink(this, DEDUCTIBLE_MODAL_REF_NAME);
            }
        },
        verifiedItacAlertBody(newValue, oldValue) {
            if (newValue !== oldValue) {
                setupModalLink(this, DEDUCTIBLE_MODAL_REF_NAME);
            }
        }
    },
    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.order.insuranceCoverage.coverageType !== coverageType.NONE) {
                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 { glassParts, supportingItems } = this.mainStore.order.lineItems;
            const availableLineItems = [
                ...(glassParts ?? []),
                ...(supportingItems ?? [])
            ];

            // 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
                    );
                case 'isDeductibleZero':
                    return (
                        this.isDeductibleVisible && this.deductibleValue <= 0
                    );
                case 'verifiedRepair':
                    return isRepair && this.isDeductibleVisible;
                case 'verifiedReplaceZeroDeductible':
                    return !isRepair && this.isDeductibleVisible && this.deductibleValue <= 0;
                case 'verifiedReplaceDeductibleOverZero':
                    return !isRepair && this.isDeductibleVisible && this.deductibleValue > 0;
                default:
                    return null;
            }
        },
        setBaseServiceLineItems(lineItems) {
            this.baseServiceLineItems = lineItems;
        },
        formatAmountInDollars,
        cancelClaim() {
            useMainStore().updateIsSafeliteProvider(false);
            useMainStore().setBailout(bailoutMessage.RequestCallback());
            this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP);
        },
        continueClaim() {
            useMainStore().updateIsSafeliteProvider(true);
            this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE);
        }
    }
};
</script>

<style lang="scss" scoped>
.iss-heritage-container-width {
    .coverage-statement-container {
        position: relative;
        min-height: 1px;
        padding-left: .9375rem;
        padding-right: .9375rem;
    }
}

.coverage-statement {
    .cost {
        color: $green;
        font-size: 2rem;
        font-weight: $font-weight-light;
        line-height: 2.75rem;
    }
    .deductible-text {
        line-height: 1.5rem;
    }
    .sub-header {
        line-height: 2rem;
    }
    :deep(ol) {
        padding: 0;
        padding-left: 1.125rem;
        padding-right: 1.125rem;
        line-height: 1.5rem;
        font-size: .875rem;

        li {
            margin-bottom: .5rem;
        }
    }
    :deep(p) {
        line-height: 1.5rem;
        font-size: 0.875rem;
        margin-bottom: 0.5rem;
        strong {
            color: $black;
        }
    }
    :deep(.body-text) {
        font-size: 0.875rem;
        line-height: 1.5rem;
    }
    :deep(.question-text) {
        margin-top: 1.5rem;
        margin-bottom: 0.5rem;
        font-size: 1rem;
        line-height: 1.5rem;
        & > span {
            text-align: left;
        }
    }
    .button-question {
        :deep(fieldset) {
            div.col:last-child {
                label {
                    margin-bottom: 0;
                }
            }
        }
    }
}

:deep(.deductible-modal) {
    p {
        margin-bottom: 0 !important;
    }
    img.mb-4 {
        margin: 0 !important;
    }
    h5 {
        color: black;
    }
    p:last-child {
        margin-top: 0.5rem;
    }
}

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