<template>
    <transition
        name="fade"
        mode="out-in">
        <div class="mobile-location-questions">
            <div
                :id="componentId"
                class="text-center">
                <label
                    for="mobileLocationLinkPromptId"
                    :aria-label="mobileLocationLinkPromptText"
                    class="form-label fw-bold w-100 ps-4 pe-4 pt-4 text-black"
                    v-html="mobileLocationLinkPromptText"></label>
                <div class="update-mobile-location-text-link">
                    <textLink
                        id="mobileLocationLinkPromptId"
                        ref="mobileLocationLink"
                        linkType="text"
                        :text="mobileLocationLinkText"
                        href="#!"
                        @click-event="openModal" />
                </div>
                <div
                    v-show="errorMessage"
                    class="row my-1 form-test-error">
                    <span
                        class="d-inline-flex small mt-0 center-error-message"
                        aria-atomic="true"
                        aria-live="polite">
                        {{ errorMessage }}
                    </span>
                </div>
                <textBlock
                    v-if="isItacOrNoComp && !isMobileFeeHidden"
                    :customText="mobileFeeText"
                    cmsWidgetName="MobileFeeDisclaimerWidget"
                    typeStyle="caption" />
            </div>
            <modal
                :ref="modalName"
                :headerText="modalHeaderText"
                :footerButtonText="modalFooterText"
                :onModalOpenedCallback="onModalOpened"
                :onModalClosedCallback="onModalClosed"
                @isModalOpened="setModalStatus"
                @footerButtonEvent="setMobileLocation">
                <template v-if="isModalOpened">
                    <addressQuestions
                        ref="addressQuestions"
                        v-model="internalModel.addressQuestions"
                        captureApartmentNumberOrBusinessName="true"
                        preserveCityAndStateOnReset="true"
                        :includeStreetAddress2="true" />
                    <vehicleProtectedQuestion
                        ref="vehicleProtectedQuestion"
                        v-model="internalModel.isVehicleProtected"
                        cmsWidgetName="VehicleProtectedQuestionWidget" />
                    <textBlock
                        cmsWidgetName="WorkspaceRequirementsWidget"
                        typeStyle="caption" />
                    <alert
                        v-if="displayInvalidZipAlert"
                        ref="alertInvalidZip"
                        class="my-4"
                        cmsWidgetName="AlertInvalidZipWidget"
                        alertClass="alert-danger"
                        :isDismissible="false" />
                </template>
            </modal>
        </div>
    </transition>
</template>

<script>
// Components
import textLink from '@/ux-components/text-link/text-link.vue';
import textBlock from '@/digital-components/text-block/text-block.vue';
import modal from '@/digital-components/modal/modal.vue';
import alert from '@/ux-components/alert/alert.vue';
import { useField } from 'vee-validate';
import addressQuestions from '@/iss-components/address-questions/address-questions.vue';

// Constants
import { experimentSettings } from '@/constants/experiments';

// Helpers
import { useMainStore } from '@/store';
import {
    getMobileZipCodeData,
    getPricedMobileFeePart,
    getServiceabilityDetails
} from '@/helpers/service-location-helper';
import { deepClone } from '@/helpers/object-helper.js';
// eslint-disable-next-line max-len
import vehicleProtectedQuestion from '@/layouts/schedule-page/service-location/mobile-location-modal-question/vehicle-protected-question/vehicle-protected-question.vue';

export default {
    name: 'mobile-location-modal-questions',
    components: {
        textLink,
        modal,
        addressQuestions,
        vehicleProtectedQuestion,
        textBlock,
        alert
    },
    props: {
        modelValue: {
            type: Object,
            default: () => ({
                addressQuestions: {
                    streetAddress: '',
                    streetAddress2: '',
                    city: '',
                    state: '',
                    zipCode: ''
                },
                isVehicleProtected: null
            })
        },
        mobileFeePart: {
            type: Object,
            default: () => ({})
        },
        linkWidgetName: String,
        modalWidgetName: String,
        alertNonServiceableZipWidgetName: String,
        alertInvalidZipWidgetName: String,
        customComponentId: String,
        validationRules: String,
        onZipUpdateCallback: {
            type: Function
        }
    },
    emits: ['update:modelValue', 'updated-mobile-fee-part', 'updated-contains-military-base', 'updated-serviceability', 'updated-mobile-ctu'],
    setup(props) {
        const uuid = crypto.randomUUID();
        const componentId = !props.customComponentId
            ? `component-${uuid}`
            : props.customComponentId;

        // Integrate this component as a single field with an object for it's value into the page level validation
        const { modelValue } = deepClone(props);
        const initialValue = modelValue;

        const fieldOptions = {
            value: modelValue,
            initialValue
        };

        const { errorMessage, handleChange, meta, validate, errors } = useField(
            componentId,
            props.validationRules,
            fieldOptions
        );

        return {
            componentId,
            errorMessage,
            handleChange,
            validate,
            meta,
            errors
        };
    },
    data() {
        return {
            internalModel: deepClone(this.modelValue),
            displayInvalidZipAlert: false,
            isModalOpened: false
        };
    },
    computed: {
        isITAC() {
            return useMainStore().isITAC;
        },
        isItacOrNoComp() {
            return this.isITAC || useMainStore().isNoComp;
        },
        isMobileFeeHidden() {
            return this.getSettingValue(experimentSettings.ISS_FEATURE_TOGGLE_IS_MOBILE_FEE_HIDDEN) === 'true';
        },
        mobileLocationLinkPromptText() {
            return this.getCmsContent(this.linkWidgetName, 'HeaderText');
        },
        mobileLocationLinkText() {
            if (
                this.addressModel.streetAddress
                && this.addressModel.streetAddress !== ''
                && this.addressModel.city
                && this.addressModel.city !== ''
                && this.addressModel.state
                && this.addressModel.state !== ''
                && this.addressModel.zipCode
                && this.addressModel.zipCode !== ''
                && this.internalModel.isVehicleProtected !== null
            ) {
                // eslint-disable-next-line max-len
                return `${this.addressModel.streetAddress}\n${this.addressModel.city}, ${this.addressModel.state} ${this.addressModel.zipCode}`;
            }
            return this.getCmsContent(this.linkWidgetName, 'BodyText');
        },
        modalName() {
            return 'MobileLocationModalWidget';
        },
        modalHeaderText() {
            return this.getCmsContent(this.modalWidgetName, 'HeaderText');
        },
        mobileFeeText() {
            const cmsContentText = this.getCmsContent('MobileFeeDisclaimerWidget', 'Text');
            return cmsContentText.replaceAll('{custom:mobileFee}', this.mobileFee);
        },
        mobileFee() {
            if (!this.mobileFeePart) {
                return 0;
            }

            return (
                this.mobileFeePart.laborAmount
                + this.mobileFeePart.sellingPrice
                + this.mobileFeePart.kitPrice
            );
        },
        modalFooterText() {
            return this.getCmsContent(this.modalWidgetName, 'FooterText');
        },
        modal() {
            return this.$refs[this.modalName];
        },
        addressModel: {
            get() {
                return this.modelValue.addressQuestions;
            }
        }
    },
    watch: {
        modelValue: {
            handler(newValue) {
                this.internalModel = deepClone(newValue);
                this.handleChange(newValue);
            },
            deep: true
        }
    },
    methods: {
        openModal() {
            this.modal.openModal();
        },
        onModalOpened() {
            this.internalModel = deepClone(this.modelValue);
        },
        setModalStatus(isOpened) {
            this.isModalOpened = isOpened;
        },
        closeModal() {
            this.modal.closeModal();
        },
        onModalClosed() {
            this.displayInvalidZipAlert = false;
            this.internalModel = deepClone(this.modelValue);
        },
        async setMobileLocation() {
            if (
                this.internalModel.addressQuestions.zipCode
                !== this.modelValue.addressQuestions.zipCode
            ) {
                // Validate the Zip Code
                const zipCodeData = await getMobileZipCodeData(this.internalModel.addressQuestions.zipCode);

                if (!zipCodeData.isValid) {
                    this.displayInvalidZipAlert = true;
                } else {
                    // retrieve mobile fee part
                    const serviceZipCode = this.internalModel.addressQuestions.zipCode;
                    const mobileFeePart = await getPricedMobileFeePart(serviceZipCode);

                    // retrieve serviceability details
                    const serviceabilityDetails = await getServiceabilityDetails(serviceZipCode);

                    // update content related to service zip code
                    this.$emit('updated-mobile-fee-part', mobileFeePart);
                    this.$emit('updated-serviceability', serviceabilityDetails.data);
                    this.$emit('updated-mobile-ctu', zipCodeData.zipCodeCtu);
                    this.$emit('updated-contains-military-base', zipCodeData.containsMilitaryBase);

                    if (this.onZipUpdateCallback) {
                        await this.onZipUpdateCallback(serviceZipCode);
                    }
                    // Update the page level model
                    this.$emit('update:modelValue', this.internalModel);

                    this.closeModal();
                }
            } else {
                // Update the page level model
                this.$emit('update:modelValue', this.internalModel);

                this.closeModal();
            }
        }
    }
};
</script>

<style lang="scss" scoped>
@import "@/styles/ux-variables-svg-strings.scss";

.mobile-location-questions {
    .center-error-message {
        justify-content: center !important;
    }
}

.update-zip-text-link::before {
    content: "";
    display: inline-block;
    width: 13px;
    height: 16px;
    background-image: url($svg-update-zip-text-link);
    background-size: contain;
    vertical-align: middle;
    margin-right: 0.5em;
}

.address-questions {
    margin-top: 0em;
}

#mobileLocationLinkPromptId {
    white-space: pre-line;
}
.text-black {
    color: $black;
}
</style>
