<script setup>
import { faQuestion, faSignOutAlt, faSpinner, faUser } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { BNavbar, BNavbarBrand, BNavbarNav } from "bootstrap-vue";
import { faGear } from "font-awesome-6";
import { storeToRefs } from "pinia";
import { computed, onMounted, ref } from "vue";
import { useRouter } from "vue-router/composables";

import {
    getOIDCIdpsWithRegistration,
    isOnlyOneOIDCProviderConfigured,
    redirectToSingleProvider,
} from "@/components/User/ExternalIdentities/ExternalIDHelper";
import { useConfig } from "@/composables/config";
import { useUserStore } from "@/stores/userStore";
import { userLogout } from "@/utils/logout";
import { withPrefix } from "@/utils/redirect";

import { loadMastheadWebhooks } from "./_webhooks";

import MastheadDropdown from "./MastheadDropdown.vue";
import MastheadItem from "./MastheadItem.vue";
import QuotaMeter from "./QuotaMeter.vue";

const { isAnonymous, currentUser } = storeToRefs(useUserStore());

const router = useRouter();
const { config, isConfigLoaded } = useConfig();

const hasOIDCRegistration = computed(() => {
    const oIDCIdps = isConfigLoaded.value ? config.value.oidc : {};
    const oIDCIdpsWithRegistration = getOIDCIdpsWithRegistration(oIDCIdps);
    if (oIDCIdpsWithRegistration) {
        return Object.keys(oIDCIdpsWithRegistration).length > 0;
    } else {
        return false;
    }
});

const hasExactlyOneOIDCRegistration = computed(() => {
    const oIDCIdps = isConfigLoaded.value ? config.value.oidc : {};
    const oIDCIdpsWithRegistration = getOIDCIdpsWithRegistration(oIDCIdps);
    if (oIDCIdpsWithRegistration) {
        return Object.keys(oIDCIdpsWithRegistration).length === 1;
    } else {
        return false;
    }
});

async function performLogin() {
    const oIDCIdps = isConfigLoaded.value ? config.value.oidc : {};
    if (config.value.disable_local_accounts && isOnlyOneOIDCProviderConfigured(oIDCIdps)) {
        const redirectUri = await redirectToSingleProvider(oIDCIdps);
        window.location = redirectUri;
    } else {
        openUrl("/login/start");
    }
}

function performRegistration() {
    if (!config.value.allow_local_account_creation && hasExactlyOneOIDCRegistration.value) {
        const oIDCIdps = isConfigLoaded.value ? config.value.oidc : {};
        const oIDCIdpsWithRegistration = getOIDCIdpsWithRegistration(oIDCIdps);
        window.location =
            oIDCIdpsWithRegistration[Object.keys(oIDCIdpsWithRegistration)[0]].end_user_registration_endpoint;
    } else {
        openUrl("/register/start");
    }
}

const props = defineProps({
    brand: {
        type: String,
        default: null,
    },
    logoUrl: {
        type: String,
        default: null,
    },
    logoSrc: {
        type: String,
        default: null,
    },
    logoSrcSecondary: {
        type: String,
        default: null,
    },
    windowTab: {
        type: Object,
        default: null,
    },
});

const extensionTabs = ref([]);
const windowToggle = ref(false);

function openUrl(url, target = null) {
    if (!target) {
        router.push(url);
    } else {
        url = withPrefix(url);
        if (target == "_blank") {
            window.open(url);
        } else {
            window.location = url;
        }
    }
}

function extensionTabClick(tab) {
    if (tab.url) {
        openUrl(tab.url, tab.target);
    } else if (typeof tab.onclick === "function") {
        tab.onclick();
    }
}

function onWindowToggle() {
    windowToggle.value = !windowToggle.value;
    props.windowTab.onclick();
}

onMounted(() => {
    loadMastheadWebhooks(extensionTabs.value);
});
</script>

<template>
    <BNavbar id="masthead" type="dark" role="navigation" aria-label="Main" class="justify-content-between">
        <BNavbarNav>
            <BNavbarBrand
                id="analysis"
                v-b-tooltip.hover
                class="ml-2 mr-2 p-0"
                title="Home"
                aria-label="homepage"
                :href="withPrefix(logoUrl)">
                <img alt="logo" :src="withPrefix(logoSrc)" />
                <img v-if="logoSrcSecondary" alt="logo" :src="withPrefix(logoSrcSecondary)" />
            </BNavbarBrand>
            <span v-if="brand" class="navbar-text py-0 px-2">
                {{ brand }}
            </span>
        </BNavbarNav>
        <BNavbarNav v-if="isConfigLoaded" class="mr-1">
            <MastheadItem
                v-if="windowTab"
                :id="windowTab.id"
                :icon="windowTab.icon"
                :toggle="windowToggle"
                :tooltip="windowTab.tooltip"
                @click="onWindowToggle" />
            <MastheadItem
                v-for="(tab, idx) in extensionTabs"
                v-show="tab.hidden !== true"
                :id="tab.id"
                :key="`extension-tab-${idx}`"
                :title="tab.title"
                :icon="tab.icon"
                :url="tab.url"
                :tooltip="tab.tooltip"
                :target="tab.target"
                @click="extensionTabClick(tab)" />
            <MastheadItem
                id="help"
                :icon="faQuestion"
                url="/about"
                tooltip="Support, Contact, and Community"
                @click="openUrl('/about')" />
            <QuotaMeter />
            <MastheadItem
                v-if="isAnonymous"
                id="user"
                class="loggedout-only"
                data-description="login masthead button"
                title="Login"
                @click="performLogin()" />
            <MastheadItem
                v-if="isAnonymous && (config.allow_local_account_creation || hasOIDCRegistration)"
                id="user-register"
                class="loggedout-only"
                data-description="register masthead button"
                title="Register"
                @click="performRegistration()" />
            <MastheadDropdown
                v-if="currentUser && !isAnonymous && !config.single_user"
                id="user"
                class="loggedin-only"
                :icon="faUser"
                :title="currentUser.username"
                tooltip="User Preferences"
                :menu="[
                    {
                        title: 'Preferences',
                        icon: faGear,
                        handler: () => openUrl('/user'),
                    },
                    {
                        title: 'Sign Out',
                        icon: faSignOutAlt,
                        handler: () => userLogout(),
                    },
                ]"
                @click="userLogout" />
            <MastheadDropdown
                v-if="currentUser && !isAnonymous && config.single_user"
                id="user"
                class="loggedin-only"
                :icon="faUser"
                :title="currentUser.username"
                tooltip="User Preferences"
                :menu="[
                    {
                        title: 'Preferences',
                        icon: faGear,
                        handler: () => openUrl('/user'),
                    },
                ]"
                @click="user" />
        </BNavbarNav>
        <FontAwesomeIcon v-else :icon="faSpinner" class="fa-spin mr-2 text-light" />
    </BNavbar>
</template>

<style scoped lang="scss">
@import "@/style/scss/theme/blue.scss";

#masthead {
    padding: 0;
    margin-bottom: 0;
    background: var(--masthead-color);
    height: var(--masthead-height);
    &:deep(.navbar-nav) {
        height: var(--masthead-height);
        & > li {
            // This allows the background color to fill the full height of the
            // masthead, while still keeping the contents centered (using flex)
            min-height: 100%;
            display: flex;
            align-items: center;
            background: var(--masthead-link-color);
            &:hover {
                background: var(--masthead-link-hover);
            }
            &.show,
            &.active {
                background: var(--masthead-link-active);
                .nav-link {
                    color: var(--masthead-text-active);
                }
            }
            .nav-link {
                position: relative;
                cursor: pointer;
                text-decoration: none;
                color: var(--masthead-text-color);
                margin-right: 0.25rem;
                margin-left: 0.25rem;
                &:hover {
                    color: var(--masthead-text-hover);
                }
                &.nav-icon {
                    font-size: 1.2em;
                    .nav-note {
                        position: absolute;
                        left: 1.6rem;
                        top: 1.6rem;
                        font-size: 0.6rem;
                        font-weight: bold;
                    }
                }
                &.toggle {
                    color: var(--masthead-text-hover);
                }
            }
        }
    }
    .navbar-brand {
        cursor: pointer;
        line-height: var(--masthead-height);
        img {
            filter: $text-shadow;
            display: inline;
            border: none;
            height: var(--masthead-logo-height);
            padding: inherit;
        }
    }
    .navbar-text {
        filter: $text-shadow;
        font-weight: bold;
        font-family: Verdana, sans-serif;
        font-size: 1rem;
        line-height: var(--masthead-height);
        color: var(--masthead-text-color);
    }
}
</style>
