<template>
    <div class="text-center mt-1">
        <div class="update-zip-text-link">
            <textLink
                id="serviceZipLinkPromptId"
                linkType="text"
                :text="serviceZipLinkText"
                href="#!"
                @clickEvent="openModal" />
        </div>
    </div>
    <modal
        :ref="modalName"
        :headerText="modalHeaderText"
        :onModalOpenedCallback="onModalOpened"
        :onModalClosedCallback="onModalClosed"
        :footerButtonText="modalFooterText"
        :modalPosition="'center'"
        @footerButtonEvent="setZipCode">
        <serviceZipQuestion
            ref="serviceZipCodeQuestion"
            v-model="internalModel.zipCode"
            customInputId="serviceZipCode"
            :cmsWidgetName="textboxQuestionWidgetName"
            v-on="{ 'textboxQuestionEvent.inputIdAssigned': onInputIdAssigned }" />
        <alert
            v-if="displayInvalidZipAlert"
            ref="alertInvalidZip"
            class="my-4"
            :cmsWidgetName="alertInvalidZipWidgetName"
            alertClass="alert-danger"
            :isDismissible="false" />
    </modal>
</template>

<script>
import textLink from '@/ux-components/text-link/text-link.vue';
import serviceZipQuestion from '@/layouts/schedule-page/service-location/service-zip-question/service-zip-question.vue';
import modal from '@/digital-components/modal/modal.vue';
import alert from '@/ux-components/alert/alert.vue';

import { getServiceabilityDetails, getZipCodeData } from '@/helpers/service-location-helper';

export default {
    name: 'service-zip-modal-question',
    components: {
        textLink,
        modal,
        serviceZipQuestion,
        alert
    },
    props: {
        modelValue: {
            type: Object,
            default: () => ({
                state: '',
                zipCode: ''
            })
        },
        modalWidgetName: String,
        onZipUpdateCallback: {
            type: Function
        }
    },
    emits: ['update:modelValue', 'updated-serviceability', 'updated-contains-military-base'],
    setup() {
        const textboxQuestionWidgetName = 'ServiceZipQuestionWidget';
        const alertInvalidZipWidgetName = 'AlertInvalidZipWidget';
        return {
            textboxQuestionWidgetName,
            alertInvalidZipWidgetName
        };
    },
    data() {
        return {
            internalModel: this.copyModel(this.modelValue),
            serviceZipCodeTextInputId: '',
            displayInvalidZipAlert: false
        };
    },
    computed: {
        serviceZipLinkText() {
            if (this.modelValue.zipCode && this.modelValue.zipCode.length > 0) {
                return `${this.modelValue.state}, ${this.modelValue.zipCode}`;
            }
            return null;
        },
        modalHeaderText() {
            return this.getCmsContent(this.textboxQuestionWidgetName, 'QuestionText');
        },
        modalFooterText() {
            return this.getCmsContent(this.modalWidgetName, 'FooterText');
        },
        modalName() {
            return this.modalWidgetName;
        }
    },
    watch: {
        modelValue(newValue) {
            this.internalModel = this.copyModel(newValue);
        },
        'internalModel.zipCode': {
            handler() {
                this.resetsOnZipInput();
            }
        }
    },
    methods: {
        resetAlerts() {
            this.displayInvalidZipAlert = false;
        },
        resetsOnZipInput() {
            this.resetAlerts();
        },
        focusOnZipInput() {
            const input = document.getElementById(this.serviceZipCodeTextInputId);
            input?.focus();
        },
        copyModel(modelToCopy) {
            return {
                state: modelToCopy.state,
                zipCode: modelToCopy.zipCode
            };
        },
        openModal() {
            this.$refs[this.modalName].openModal();
        },
        closeModal() {
            this.$refs[this.modalName].closeModal();
        },
        onInputIdAssigned(inputId) {
            this.serviceZipCodeTextInputId = inputId;
        },
        onModalOpened() {
            this.internalModel.zipCode = this.modelValue.zipCode;
            this.focusOnZipInput();
        },
        onModalClosed() {
            this.internalModel.zipCode = this.modelValue.zipCode;
            this.resetsOnZipInput();
        },
        async setZipCode() {
            if (this.internalModel.zipCode !== this.modelValue.zipCode) {
                this.resetAlerts();

                const zipCodeData = await getZipCodeData(this.internalModel.zipCode);

                if (!zipCodeData.isValid) {
                    this.displayInvalidZipAlert = true;
                    this.focusOnZipInput();
                } else {
                    this.internalModel.state = zipCodeData.state;
                    const serviceZipCode = this.internalModel.zipCode;

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

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

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

                    this.closeModal();
                }
            } else {
                this.closeModal();
            }
        },
        getZipCodeData
    }
};
</script>

<style lang="scss" scoped>
@import "@/styles/ux-variables-svg-strings.scss";
a#serviceZipLinkPromptId {
    line-height: 26px;
}

.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;
}
</style>
