<template>
    <!-- Modal -->
    <div
        :id="modalId"
        class="modal fade modal-component"
        tabindex="-1"
        aria-labelledby="ModalComponentLabel"
        aria-hidden="true"
        @keydown.enter="onKeyDown"
        v-on="{
            'hidden.bs.modal': onModalClosed,
            'shown.bs.modal': onModalOpened
        }">
        <div class="modal-dialog"
            :class="{
                'modal-dialog-edge': modalPosition === modalPositions.edge,
                'modal-dialog-centered': modalPosition === modalPositions.center
            }">
            <div
                class="modal-content"
                role="dialog"
                aria-modal="true">
                <div class="modal-header mb-2 mt-2">
                    <span
                        v-if="headerText"
                        class="modal-title d-flex justify-content-center pb-0 w-100"
                        :innerHTML="headerText">
                    </span>
                    <button
                        ref="closeButton"
                        type="button"
                        class="btn-close"
                        aria-label="Close"
                        @mousedown="closeModal"
                        @keypress.space="closeModal"></button>
                </div>
                <div class="modal-body ps-5 pe-5 pb-5 pt-1">
                    <slot></slot>
                </div>
                <div class="modal-footer px-5 py-4">
                    <buttonMain
                        id="modalbtn"
                        ref="modalButtonMain"
                        :variant="buttonVariant"
                        class="w-100"
                        :buttonText="footerButtonText"
                        pushToGA
                        :class="[
                            (isButtonDisabled || isFooterButtonDisabled) &&
                            'form-test-invalid'
                        ]"
                        @clickEvent="validateAndEmit" />
                </div>
            </div>
        </div>
    </div>
</template>

<script>
import ButtonMain from '@/ux-components/button-main/button-main.vue';
import { Modal } from 'bootstrap';
import { useForm } from 'vee-validate';
import { modalPositions } from '@/constants/component-variants';

export default {
    // eslint-disable-next-line vue/multi-word-component-names
    name: 'modal',
    components: {
        ButtonMain
    },
    props: {
        modalId: String,
        headerText: String,
        footerButtonText: String,
        onModalOpenedCallback: {
            type: Function
        },
        onModalClosedCallback: {
            type: Function
        },
        isButtonDisabled: Boolean,
        buttonVariant: {
            type: String,
            default: 'success'
        },
        modalPosition: {
            type: String,
            default: modalPositions.edge
        },
        allowInvalidSubmit: {
            type: Boolean,
            default: false
        }
    },
    emits: ['footer-button-event', 'isModalOpened'],
    setup(props) {
        const modalId = props.modalId
            ? props.modalId
            : `modal-${crypto.randomUUID()}`;

        const { meta, validate, resetForm } = useForm();

        // TODO: Correct Duplicate key 'modalId' issue.
        // Probably just rename the prop. -br
        return {
            // eslint-disable-next-line vue/no-dupe-keys
            modalId,
            meta,
            validate,
            resetForm,
            modalPositions
        };
    },
    computed: {
        isFooterButtonDisabled() {
            if (!this.meta.touched) {
                return !this.meta.valid;
            }
            return !this.meta.dirty || !this.meta.valid;
        }
    },
    watch: {
        $route() {
            this.closeModal();
        }
    },
    methods: {
        async validateAndEmit() {
            const validationResult = await this.validate();
            if (validationResult.valid || this.allowInvalidSubmit) {
                this.$emit('footer-button-event');
            }
        },
        async onKeyDown(e) {
            e.preventDefault();
            document.getElementById('modalbtn')?.focus();
            this.$refs.modalButtonMain.clicked();
            document.getElementById(this.modalId)?.focus();
        },
        onModalOpened() {
            this.onModalOpenedCallback?.();
        },
        onModalClosed() {
            this.onModalClosedCallback?.();
        },
        openModal() {
            const modal = Modal.getOrCreateInstance(document.getElementById(this.modalId));
            modal?.show();
            this.$emit('isModalOpened', true);
        },
        closeModal() {
            const modal = Modal.getInstance(document.getElementById(this.modalId));
            modal?.hide();
            this.$emit('isModalOpened', false);
        }
    }
};
</script>

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

.modal {
    top: auto;
    bottom: 0;
    h5,
    strong,
    .subheader-text {
        color: $black;
    }
    .modal-header {
        padding: 1.5rem 0 0.5rem 0;
        border-bottom: none;
        .btn-close {
            position: absolute;
            right: 1rem;
            top: 1rem;
            background-image: url($svg-modal-header-button-close);
            opacity: 1;
        }

        .modal-title {
            font-weight: 500;
            font-size: 1.25rem;
            line-height: 2rem;
            color: $black;
        }
    }
    .modal-footer {
        position: sticky;
        width: 100%;
        bottom: 0;
        z-index: 5;
        border-radius: 0;
        background-color: $gray-100;

        > .navigation-link {
            color: $black;
            font-weight: $font-weight-bold;
            line-height: 1.625rem;
            white-space: nowrap;
            align-items: center;
            text-decoration: underline;
            text-underline-offset: .3125rem;
        }
    }
    &.modal-component {
        .modal-dialog {
            display: flex;
            max-width: 47.9375rem;
            .modal-content {
                margin: 1.5rem auto 0 auto;
                .modal-body {
                    .col {
                        max-width: 100%;
                    }
                    .modal-sub-body {
                        color: $gray-600;
                    }
                    ul {
                        margin-bottom: 0;
                    }
                    p {
                        &:last-child {
                            margin-bottom: 0;
                        }
                    }
                    @include media-breakpoint-up(md) {
                        overflow: auto;
                        flex: none;
                    }
                    h5 {
                        text-align: left;
                        line-height: 2rem;
                    }
                }
            }
            &.modal-dialog-edge {
                min-height: 100%;
                margin: 0 auto;
                align-items: flex-end;
                @include media-breakpoint-up(md) {
                    align-items: inherit;
                    width: 23.5rem;
                    position: absolute;
                    top: 0;
                    right: 0;
                    transform: translate(100%);
                }
                .modal-content {
                    box-shadow: 0px 1rem 3rem -1rem rgba(0, 0, 0, 0.25);
                    border-radius: 1.5rem 1.5rem 0 0;
                    @include media-breakpoint-up(md) {
                        box-shadow: none;
                        border-radius: 0;
                        margin: 0 auto;
                    }
                }
            }
            &.modal-dialog-centered {
                .modal-content {
                    box-shadow: 0px 1rem 3rem -1rem rgba(0, 0, 0, 0.25);
                    border-radius: 1.5rem;
                    overflow: auto;
                }
                .modal-header {
                    justify-content: center;
                }
            }
        }
        &.show .modal-dialog {
            &.modal-dialog-edge {
                @include media-breakpoint-up(md) {
                    transform: translateY(0);
                }
            }
        }
        .modal-footer {
            border-top: none;

            button {
                margin: 0;
            }
        }
    }
    @include media-breakpoint-up(md) {
        &.fade {
            transition: opacity 0.25s linear;
        }
    }
}
body {
    .modal-backdrop {
        height: 100%;
        &.show {
            opacity: 0.4;
        }
    }
}
</style>
