<template>
    <div
        class="alert fade show"
        role="alert"
        :class="[
            isDismissible ? 'alert-dismissible' : '',
            alertClass,
            cssClassNameForCmsWidget,
        ]">
        <div
            class="alert-header"
            :class="{
                'collapsible-header': isCollapsible
            }"
            @click="toggleCollapse">
            <div class="alert-icon-container">
                <svg
                    class="alert-icon"
                    xmlns="http://www.w3.org/2000/svg"
                    width="20"
                    height="21"
                    viewBox="0 0 20 21">
                    <path
                        fill-rule="nonzero"
                        d="M10 .5c5.523 0 10 4.477 10 10s-4.477 10-10 10-10-4.477-10-10S4.477.5 10 .5zm.043 13.6a1
                        1 0 1 0 0 2 1 1 0 0 0 0-2zm.77-9.2h-1.54l-.088.009a.502.502 0 0 0-.299.193.66.66 0 0
                        0-.125.47l.747 6.806.017.096c.065.249.263.425.495.426l.084-.008c.22-.042.396-.246.427-.51l.793-6.805.004-.102a.651.651
                        0 0 0-.127-.37.489.489 0 0 0-.388-.205z" />
                </svg>
            </div>
            <template v-if="alertHeadline">
                <div class="alert-headline-text-container">
                    <span class="m-0 alert-header-text d-block">
                        {{ alertHeadline }}
                    </span>
                    <slot name="headline-line-two"></slot>
                </div>
            </template>
            <div class="alert-icon-container">
                <button
                    v-if="isCollapsible"
                    class="btn-collapse"
                    type="button">
                    <svg
                        xmlns="http://www.w3.org/2000/svg"
                        width="15"
                        height="9"
                        viewBox="0 0 15 9"
                        class="btn-collapse-icon"
                        :class="{ 'rotated': !collapsed }">
                        <path
                            fill-rule="nonzero"
                            d="M7.5 0a.806.806 0 0 0-.593.265L.246 7.455a.957.957 0 0 0 0 1.28.796.796 0 0 0
                            1.185 0l6.07-6.55 6.068 6.55a.796.796 0 0 0 1.186 0 .957.957 0 0 0 0-1.28L8.093.265A.806.806
                            0 0 0 7.5 0" />
                    </svg>
                </button>
                <button
                    v-if="isDismissible"
                    type="button"
                    class="btn-dismiss"
                    data-bs-dismiss="alert"
                    aria-label="Close">
                    <svg
                        xmlns="http://www.w3.org/2000/svg"
                        viewBox="0 0 23.7 23.7"
                        class="btn-dismiss-icon"
                        xml:space="preserve">
                        <path
                            d="m23.24 2.7-9.15 9.15L23.24 21a1.581 1.581 0 0 1-1.12 2.7c-.42 0-.82-.16-1.12-.46l-9.15-9.15-9.15 9.15c-.3.3-.7.46-1.12.46A1.581
                            1.581 0 0 1 .46 21l8.47-8.47.68-.68L.46 2.7c-.62-.62-.62-1.62 0-2.24.62-.62 1.62-.62 2.24 0l8.47 8.47.68.68L21
                            .46a1.57 1.57 0 0 1 2.23 0c.63.62.63 1.62.01 2.24z" />
                    </svg>
                </button>
            </div>
        </div>
        <div
            v-show="alertCopy"
            :id="collapseId"
            class="collapse"
            :class="{ 'show': !startCollapsed }">
            <div class="alert-body">
                <template
                    v-for="paragraph in splitAlertCopyForParagraphTag"
                    :key="paragraph">
                    <p
                        v-if="!doesCopyContainRouterLink(paragraph) && !doesCopyContainTextLink(paragraph)"
                        class="m-0 text-body"
                        v-html="paragraph"></p>
                    <p
                        v-else
                        class="m-0 text-body">
                        <template v-if="doesCopyContainRouterLink(paragraph)">
                            <textBlock
                                :customText="paragraph"
                                class="mb-1"
                                :marginTopSizeOverride="0" />
                        </template>
                        <template
                            v-for="copy in splitCopyOnCMSPlaceHolder(paragraph)"
                            v-else
                            :key="copy">
                            <span v-if="doesCopyContainTextLink(copy)">
                                <textLink
                                    linkType="text"
                                    :text="getRouterLinkDisplayTextFromCopy(copy)"
                                    href="#!"
                                    :data-bs-target="'#' + getRouterLinkRouteFromCopy(copy)"
                                    :preventDefaultOnClick="preventDefaultOnClick"
                                    @clickEvent="$emit('textLinkClicked', getRouterLinkRouteFromCopy(copy))" />
                            </span>
                            <span
                                v-else
                                v-html="copy"></span>
                        </template>
                    </p>
                </template>
            </div>
        </div>
    </div>
</template>

<script>
import {
    doesCopyContainRouterLink,
    doesCopyContainTextLink,
    splitCopyOnCMSPlaceHolder,
    getRouterLinkRouteFromCopy,
    getRouterLinkDisplayTextFromCopy,
    splitCMSCopyOnParagraphTag
} from '@/helpers/cms-content-helper';
import applicationConfig from '@/constants/application-config';
import textBlock from '@/digital-components/text-block/text-block.vue';
import textLink from '@/ux-components/text-link/text-link.vue';
import { Collapse } from 'bootstrap';

export default {
    name: 'alert',
    components: {
        textBlock,
        textLink
    },
    props: {
        isDismissible: Boolean,
        isCollapsible: Boolean,
        /*
        alertClass class names:
        alert-success (green)
        alert-danger (red)
        alert-warning (yellow)
        alert-info (blue)
        */
        alertClass: String,
        cmsWidgetName: {
            type: String,
            default(rawProps) {
                if (!rawProps.cmsWidgetName) {
                    window.console.log('Error: Missing a CMS Widget Name (required field)');
                }
                return 'widgetUndefined';
            }
        },
        manualHeadline: String,
        manualHeadlineLineTwo: {
            type: String,
            default: ''
        },
        manualCopy: String,
        shouldScrollToOnMount: {
            type: Boolean,
            default: true
        },
        startCollapsed: {
            type: Boolean,
            default: false
        },
        preventDefaultOnClick: { type: Boolean, required: false, default: false }
    },
    emits: ['textLinkClicked'],
    data() {
        return {
            collapsed: this.startCollapsed || false,
            collapseElement: null
        };
    },
    computed: {
        pageQueryString() {
            return applicationConfig.PAGE_QUERYSTRING;
        },
        alertHeadline() {
            return this.manualHeadline
                ? this.manualHeadline
                : this.getCmsContent(this.cmsWidgetName, 'HeadlineText');
        },
        alertHeadlineLineTwo() {
            return this.manualHeadlineLineTwo
                ? this.manualHeadlineLineTwo
                : '';
        },
        alertCopy() {
            return this.manualCopy
                ? this.manualCopy
                : this.getCmsContent(this.cmsWidgetName, 'BodyText');
        },
        hasManualHeadlineLineTwo() {
            return this.manualHeadlineLineTwo !== '';
        },
        splitAlertCopyForParagraphTag() {
            return splitCMSCopyOnParagraphTag(this.alertCopy);
        },
        collapseId() {
            return this.isCollapsible
                ? `${this.cmsWidgetName}-collapse`
                : null;
        }
    },
    mounted() {
        this.ensureAlertIsInViewPort();
        if (this.isCollapsible) {
            this.collapseElement = Collapse.getOrCreateInstance(document.getElementById(this.collapseId), { toggle: false });
        }
    },
    methods: {
        doesCopyContainRouterLink,
        doesCopyContainTextLink,
        splitCopyOnCMSPlaceHolder,
        getRouterLinkRouteFromCopy,
        getRouterLinkDisplayTextFromCopy,
        ensureAlertIsInViewPort() {
            if (this.shouldScrollToOnMount && this.$el.style?.display !== 'none') {
                const footerHeight = this.getFooterInfoBoxHeight();
                if (!this.isAlertInViewport(footerHeight)) {
                    this.$el.scrollIntoView(true); // 'true' attempts to scroll element to top of viewport
                }
            }
        },
        isAlertInViewport(footerHeight) {
            const rect = this.$el.getBoundingClientRect();
            return (
                rect.top >= 0
                // remove footerHeight from window height to avoid items being hidden behind footer
                && rect.bottom
                    <= (window.innerHeight - footerHeight
                        || document.documentElement.clientHeight - footerHeight)
            );
        },
        toggleCollapse() {
            if (!this.isCollapsible) {
                return;
            }
            this.collapsed = !this.collapsed;
            if (this.collapsed) {
                this.collapseElement.hide();
            } else {
                this.collapseElement.show();
            }
        }
    }
};
</script>

<style lang="scss" scoped>
.alert {
    border: 1px solid;
    padding: 0rem;
    margin-bottom: 2rem;
    .alert-headline-text-container {
        flex-grow: 1;
        padding: 0rem 0.625rem;

        .alert-header-text {
            padding: 0;
        }
    }
    .alert-header {
        display: flex;
        align-items: flex-start;
        justify-content: center;
        flex-direction: row;
        padding: .75rem 1rem .75rem 1rem;
        font-weight: 600;
        color: $black;
        &.collapsible-header {
            cursor: pointer;
        }
    }
    .alert-icon-container {
        display: flex;
        align-items: center;
        height: 1.625rem;
    }
    .alert-icon {
        min-width: 1rem;
        max-height: 1rem;
    }
    .alert-header-text {
        flex-grow: 1;
        padding: 0rem .625rem;
    }
    .btn-collapse {
        display: flex;
        border: none;
        background: none;
        min-width: 1rem;
        max-height: 1rem;
        padding: 0;
    }
    .btn-collapse-icon {
        height: 100%;
        width: 100%;
        transition: transform 0.3s;
        transform: rotate(180deg);
        &.rotated {
            transform: none;
        }
    }
    .btn-dismiss {
        display: flex;
        border: none;
        background: none;
        min-width: 1rem;
        max-height: 1rem;
        padding: 0;
    }
    .btn-dismiss-icon {
        height: 100%;
        width: 100%;
    }
    a {
        font-weight: $font-weight-normal;
    }
    border-color: transparent;
    .alert-body {
        margin: 0 1rem;
        padding: .5rem 1rem .75rem 1rem;
        border-top: 1px solid;
        color: $darker-gray;
        line-height: 1.625rem;
        font-weight: 400;
    }
    &.alert-info {
        background-color: $blue-100;
        border-color: $blue-200;
        .alert-body {
            border-top-color: $blue-200;
        }
        svg {
            fill: $blue-700;
            width: 1rem;
            height: 1rem;
        }
    }
    &.alert-danger {
        background-color: $alert-red-bg;
        border-color: $alert-red-color;
        .alert-body {
            border-top-color: $alert-red-color;
        }
        svg {
            fill: $alert-red-color;
            width: 1rem;
            height: 1rem;
        }
    }
    &.alert-warning {
        background-color: $alert-yellow-bg;
        border-color: $alert-yellow-color;
        .alert-body {
            border-top-color: $alert-yellow-color;
        }
        svg {
            fill: $alert-yellow-color;
        }
    }
    &.alert-success {
        background-color: $green-100;
        border-color: $green-200;
        .alert-body {
            border-top-color: $green-200;
        }
        svg {
            fill: $green-700;
            width: 1rem;
            height: 1rem;
        }
    }
}
</style>
