<template>
    <buttonQuestion
        ref="buttonQuestion"
        :answers="servicePackageAnswers"
        :groupName="groupName"
        buttonTypeString="servicePackageRadio"
        :buttonTypeObject="servicePackageRadio"
        v-model="selectedPackageName"
        :validationRules="validationRules"
        :isRequired="isRequired"
        :logDisplayedValuesEvent="true" />
</template>

<script>
import buttonQuestion from "@/digital-components/button-question/button-question";
import baseMixin from "@/mixins/base-mixin.js";
import { processIfStatements } from "@/helpers/cms-content-helper";
import { damageLocationsSelected as glassLocations } from "@/constants/damage-locations-selected";
import servicePackageRadio from "./service-package-radio/service-package-radio";
import { partTypeStrings } from "@/constants/part-type-strings";
import { packageNames } from "@/constants/package-names";
import {
    shouldFrontWipersBeAvailable,
    shouldRearWipersBeAvailable,
    shouldRainDefenseBeAvailable,
    getAvailablePackages,
    getHighestRequiredTier,
    getPackageContents,
    containsLineItemWithPartType,
    findLineItemsWithPartType,
} from "@/helpers/service-package-helper";
import {
    getPromosThatMatchLineItemsOnOrder,
    removeVapsPromosFromPromoArray,
} from "@/helpers/promotions-helper";

export default {
    name: "servicePackageQuestion",
    props: {
        groupName: String,
        cashCmsWidgetName: String,
        insuranceCmsWidgetName: String,
        validationRules: String,
        isRequired: Boolean,
        isInsuranceSelected: Boolean,
        availableLineItems: null,
        activePromos: null,
    },
    data() {
        return {
            servicePackageRadio: servicePackageRadio,
            selectedPackageName: null,
        };
    },
    watch: {
        availableLineItems() {
            if (this.$store.getters.payment.isInsurance != null) {
                this.selectDefaultPackage();
            }
        },
        selectedPackageName(newValue) {
            const VapsProductsInSelectedPackage = this.getVapsLineItemsForSelectedPackage(newValue);
            this.$emit("vapsItemsSelected", VapsProductsInSelectedPackage);
        },
    },
    computed: {
        nullSafeAvailableLineItems() {
            return this.availableLineItems ?? [];
        },
        servicePackageAnswers() {
            const cmsWidgetName = this.isInsuranceSelected
                ? this.insuranceCmsWidgetName
                : this.cashCmsWidgetName;
            let cmsAnswersContent = this.getCmsContent(cmsWidgetName, "Answers");
            if (!cmsAnswersContent) {
                return null;
            }

            const availablePackages = getAvailablePackages(
                this.glassToReplace,
                this.nullSafeAvailableLineItems,
                this.isRepair
            );

            cmsAnswersContent = cmsAnswersContent.filter((answer) =>
                availablePackages.some((tier) => answer.Name === tier.packageName)
            );

            const modifiedAnswers = cmsAnswersContent.map((answer) => ({
                value: answer.Name,
                buttonLabel: this.getHeaderTextFromCms(answer.SubWidgetName),
                buttonLabelSubCopy: this.getSubheaderTextFromCms(answer.SubWidgetName),
                buttonBodyCopy: this.getBodyTextFromCms(answer.SubWidgetName),
                buttonAuxillaryCopy: this.getDiscountedPackagePriceString(answer.Name),
                buttonFooterCopy: this.getFooterTextFromCms(answer.SubWidgetName),
                additionalButtonData: {
                    strikeThroughPrice: this.getPackagePriceString(answer.Name),
                },
            }));
            return modifiedAnswers;
        },
        isRecalibrationOnOrder() {
            return containsLineItemWithPartType(
                partTypeStrings.RECALIBRATION,
                this.nullSafeAvailableLineItems
            );
        },
        frontWipersApplicableForTierTwo() {
            return shouldFrontWipersBeAvailable(
                this.glassToReplace,
                this.nullSafeAvailableLineItems,
                this.isRepair,
                packageNames.TIER_TWO
            );
        },
        rearWiperApplicableForTierTwo() {
            return shouldRearWipersBeAvailable(
                this.glassToReplace,
                this.nullSafeAvailableLineItems,
                this.isRepair,
                packageNames.TIER_TWO
            );
        },
        frontWipersApplicableForTierThree() {
            return shouldFrontWipersBeAvailable(
                this.glassToReplace,
                this.nullSafeAvailableLineItems,
                this.isRepair,
                packageNames.TIER_THREE
            );
        },
        rearWiperApplicableForTierThree() {
            return shouldRearWipersBeAvailable(
                this.glassToReplace,
                this.nullSafeAvailableLineItems,
                this.isRepair,
                packageNames.TIER_THREE
            );
        },
        rainDefenseApplicableForTierThree() {
            return shouldRainDefenseBeAvailable(
                this.glassToReplace,
                this.nullSafeAvailableLineItems,
                this.isRepair,
                packageNames.TIER_THREE
            );
        },
        glassToReplace() {
            return this.$store.getters.order.damage.glassToReplace;
        },
        isRepair() {
            return this.$store.getters.order.damage.isRepair;
        },
    },
    methods: {
        processIfStatements,
        getHeaderTextFromCms(cmsWidgetName) {
            return this.getCmsContent(cmsWidgetName, "HeaderText");
        },
        getSubheaderTextFromCms(cmsWidgetName) {
            return this.getCmsContent(cmsWidgetName, "SubheaderText");
        },
        getBodyTextFromCms(cmsWidgetName) {
            const bodyText = this.getCmsContent(cmsWidgetName, "BodyText");
            return this.processIfStatements(bodyText, "custom", this.getCustomValueFromString);
        },
        getFooterTextFromCms(cmsWidgetName) {
            const footerText = this.getCmsContent(cmsWidgetName, "FooterText");
            return this.processIfStatements(footerText, "custom", this.getCustomValueFromString);
        },
        getPackagePriceString(packageName) {
            const formattedPriceFloat = parseFloat(
                this.getPackagePrice(packageName, { discountedPrice: false })
            ).toFixed(2);
            return "$" + formattedPriceFloat;
        },
        getDiscountedPackagePriceString(packageName) {
            const formattedPriceFloat = parseFloat(
                this.getPackagePrice(packageName, { discountedPrice: true })
            ).toFixed(2);
            return (this.isInsuranceSelected ? "As little as $" : "$") + formattedPriceFloat;
        },
        getPackagePrice(packageName, { discountedPrice = false }) {
            const lineItemsToPrice = [...this.nullSafeAvailableLineItems];
            if (discountedPrice) {
                lineItemsToPrice.push(...removeVapsPromosFromPromoArray(this.activePromos));
            }
            let priceFloat = this.isInsuranceSelected
                ? 0
                : baseMixin.methods.getTierOnePackagePrice(
                      baseMixin.methods.filterOutFees(lineItemsToPrice)
                  );

            priceFloat += this.getVapsPrice(packageName, discountedPrice);

            return priceFloat;
        },
        getVapsPrice(packageName, applyPromoDiscounts = false) {
            const vapsItems = this.getVapsLineItemsForSelectedPackage(packageName);

            let price = 0;

            vapsItems.forEach((item) => {
                price += baseMixin.methods.getTotalLineItemPrice(item);
            });

            if (applyPromoDiscounts && this.activePromos) {
                const relevantPromos = getPromosThatMatchLineItemsOnOrder(
                    this.activePromos,
                    vapsItems
                );
                relevantPromos.forEach((promo) => {
                    price += baseMixin.methods.getTotalLineItemPrice(promo);
                });
            }

            return price;
        },
        selectDefaultPackage() {
            const vapsFromStore = this.$store.getters.lineItems.vaps ?? [];

            this.selectedPackageName = getHighestRequiredTier(
                this.glassToReplace,
                this.nullSafeAvailableLineItems,
                this.isRepair,
                vapsFromStore
            );
        },
        getVapsLineItemsForSelectedPackage(packageName) {
            const packageContentTypes = getPackageContents(
                this.glassToReplace,
                this.nullSafeAvailableLineItems,
                this.isRepair,
                packageName
            );

            let vapsLineItemsForSelectedPackage = [];

            packageContentTypes.forEach((vapType) => {
                vapsLineItemsForSelectedPackage.push(
                    ...findLineItemsWithPartType(vapType, this.nullSafeAvailableLineItems)
                );
            });

            return vapsLineItemsForSelectedPackage;
        },
        getCustomValueFromString(str) {
            switch (str) {
                case "isRecalibrationOnOrder":
                    return this.isRecalibrationOnOrder;
                case "frontWipersApplicableForTierTwo":
                    return this.frontWipersApplicableForTierTwo;
                case "rearWiperApplicableForTierTwo":
                    return this.rearWiperApplicableForTierTwo;
                case "frontWipersApplicableForTierThree":
                    return this.frontWipersApplicableForTierThree;
                case "rearWiperApplicableForTierThree":
                    return this.rearWiperApplicableForTierThree;
                case "rainDefenseApplicableForTierThree":
                    return this.rainDefenseApplicableForTierThree;
                default:
                    return null;
            }
        },
    },
    components: {
        buttonQuestion,
    },
};
</script>
