<template>
  <nav class="bg-yellow-100 z-50">
    <div class="max-w-7xl mx-auto px-2 sm:px-6 lg:px-8">
      <div class="relative flex items-center justify-between h-16">
        <div class="absolute inset-y-0 left-0 flex items-center sm:hidden">
          <!-- Mobile menu button-->
          <button
            type="button"
            class="
              inline-flex
              items-center
              justify-center
              p-2
              rounded-md
              text-gray-400
              hover:text-white hover:bg-yellow-400
              focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white
            "
            aria-controls="mobile-menu"
            aria-expanded="false"
          >
            <span class="sr-only">{{ $t("Open main menu") }}</span>
            <!--
            Icon when menu is closed.

            Heroicon name: outline/menu

            Menu open: "hidden", Menu closed: "block"
          -->
            <svg
              class="block h-6 w-6"
              xmlns="http://www.w3.org/2000/svg"
              fill="none"
              viewBox="0 0 24 24"
              stroke="currentColor"
              aria-hidden="true"
            >
              <path
                stroke-linecap="round"
                stroke-linejoin="round"
                stroke-width="2"
                d="M4 6h16M4 12h16M4 18h16"
              />
            </svg>
            <!--
            Icon when menu is open.

            Heroicon name: outline/x

            Menu open: "block", Menu closed: "hidden"
          -->
            <svg
              class="hidden h-6 w-6"
              xmlns="http://www.w3.org/2000/svg"
              fill="none"
              viewBox="0 0 24 24"
              stroke="currentColor"
              aria-hidden="true"
            >
              <path
                stroke-linecap="round"
                stroke-linejoin="round"
                stroke-width="2"
                d="M6 18L18 6M6 6l12 12"
              />
            </svg>
          </button>
        </div>
        <div
          class="
            flex-1 flex
            items-center
            justify-center
            sm:items-stretch sm:justify-start
          "
        >
          <div class="flex-shrink-0 flex items-center">
            <img
              class="block lg:hidden h-8 w-auto"
              src="https://tailwindui.com/img/logos/workflow-mark-indigo-500.svg"
              alt="Workflow"
            />
            <router-link :to="{ name: RouteName.HOME }">
              <logo class="hidden lg:block h-8 w-auto" />
            </router-link>
          </div>
          <div class="hidden sm:block sm:ml-6">
            <div class="flex items-center space-x-4">
              <router-link
                :to="{ name: RouteName.SEARCH }"
                class="
                  text-gray-700
                  hover:bg-yellow-400 hover:text-black
                  px-3
                  py-2
                  rounded-md
                  text-sm
                  font-medium
                "
                >{{ $t("Explore") }}</router-link
              >

              <router-link
                :to="{ name: RouteName.MY_EVENTS }"
                v-if="currentActor.id && currentUser.isLoggedIn"
                class="
                  text-gray-700
                  hover:bg-yellow-400 hover:text-black
                  px-3
                  py-2
                  rounded-md
                  text-sm
                  font-medium
                "
                >{{ $t("My events") }}</router-link
              >

              <router-link
                :to="{ name: RouteName.MY_GROUPS }"
                v-if="
                  config &&
                  config.features.groups &&
                  currentActor.id &&
                  currentUser.isLoggedIn
                "
                class="
                  text-gray-700
                  hover:bg-yellow-400 hover:text-black
                  px-3
                  py-2
                  rounded-md
                  text-sm
                  font-medium
                "
                >{{ $t("My groups") }}</router-link
              >

              <router-link
                v-if="!hideCreateEventsButton"
                :to="{ name: RouteName.CREATE_EVENT }"
                class="
                  p-2
                  pl-5
                  pr-5
                  transition-colors
                  duration-700
                  transform
                  bg-indigo-500
                  hover:bg-blue-400
                  text-gray-100
                  rounded-lg
                  focus:border-4
                  border-indigo-300
                "
              >
                {{ $t("Create") }}
              </router-link>

              <a
                v-if="config && config.features.koenaConnect"
                class="koena"
                href="https://mediation.koena.net/framasoft/mobilizon/"
                target="_blank"
                rel="noopener external"
                hreflang="fr"
              >
                <img
                  src="/img/koena-a11y.svg"
                  width="150"
                  alt="Contact accessibilité"
                />
              </a>
            </div>
          </div>
        </div>
        <div
          class="
            absolute
            inset-y-0
            right-0
            flex
            items-center
            pr-2
            sm:static sm:inset-auto sm:ml-6 sm:pr-0
          "
        >
          <div>
            <search-field @navbar-search="mobileNavbarActive = false" />
          </div>
          <!-- Profile dropdown -->
          <div class="ml-3 relative">
            <div>
              <button
                type="button"
                class="
                  bg-gray-800
                  flex
                  text-sm
                  rounded-full
                  focus:outline-none
                  focus:ring-2
                  focus:ring-offset-2
                  focus:ring-offset-gray-800
                  focus:ring-white
                "
                id="user-menu-button"
                aria-expanded="false"
                aria-haspopup="true"
                @click="toggleMenu"
              >
                <span class="sr-only">{{ $t("Open user menu") }}</span>
                <img
                  v-if="currentActor.avatar"
                  class="h-8 w-8 rounded-full"
                  :src="currentActor.avatar.url"
                  alt=""
                />
                <o-icon v-else icon="account-circle" />
              </button>
            </div>

            <!--
            Dropdown menu, show/hide based on menu state.

            Entering: "transition ease-out duration-100"
              From: "transform opacity-0 scale-95"
              To: "transform opacity-100 scale-100"
            Leaving: "transition ease-in duration-75"
              From: "transform opacity-100 scale-100"
              To: "transform opacity-0 scale-95"
          -->
            <div
              v-show="userDropDownOpened"
              class="
                origin-top-right
                absolute
                right-0
                mt-2
                w-48
                rounded-md
                shadow-lg
                py-1
                bg-white
                ring-1 ring-black ring-opacity-5
                focus:outline-none
              "
              role="menu"
              aria-orientation="vertical"
              aria-labelledby="user-menu-button"
              tabindex="-1"
            >
              <button
                v-for="identity in identities"
                :active="identity.id === currentActor.id"
                :key="identity.id"
                @click="setIdentity(identity)"
                @keyup.enter="setIdentity(identity)"
                class="
                  block
                  px-4
                  py-2
                  text-sm text-gray-700
                  hover:bg-yellow-400 hover:text-black
                  w-full
                "
                role="menuitem"
                tabindex="-1"
                id="user-menu-item-2"
              >
                <div class="flex text-left">
                  <div>
                    <div
                      v-if="identity.avatar"
                      class="
                        rounded-full
                        h-8
                        w-8
                        bg-gray-500
                        flex
                        items-center
                        justify-center
                        overflow-hidden
                      "
                    >
                      <img :src="identity.avatar.url" alt="" />
                    </div>
                    <o-icon v-else size="is-medium" icon="account-circle" />
                  </div>
                  <div class="flex flex-col">
                    <span class="ml-2 font-bold text-sm">{{
                      displayName(identity)
                    }}</span>

                    <span
                      class="ml-2 text-sm text-gray-600 dark:text-gray-400"
                      v-if="identity.name"
                      >@{{ identity.preferredUsername }}</span
                    >
                  </div>
                </div>
              </button>

              <!-- Active: "bg-gray-100", Not Active: "" -->
              <router-link
                :to="{ name: RouteName.UPDATE_IDENTITY }"
                class="
                  block
                  px-4
                  py-2
                  text-sm text-gray-700
                  hover:bg-yellow-400 hover:text-black
                "
                role="menuitem"
                tabindex="-1"
                id="user-menu-item-0"
                >{{ $t("My account") }}</router-link
              >
              <router-link
                v-if="currentUser.role === ICurrentUserRole.ADMINISTRATOR"
                :to="{ name: RouteName.ADMIN_DASHBOARD }"
                class="
                  block
                  px-4
                  py-2
                  text-sm text-gray-700
                  hover:bg-yellow-400 hover:text-black
                "
                role="menuitem"
                tabindex="-1"
                id="user-menu-item-1"
                >{{ $t("Administration") }}</router-link
              >
              <button
                @click="logout"
                @keyup.enter="logout"
                class="
                  block
                  px-4
                  py-2
                  text-sm text-gray-700
                  hover:bg-yellow-400 hover:text-black
                  text-left
                  w-full
                "
                role="menuitem"
                tabindex="-1"
                id="user-menu-item-2"
              >
                {{ $t("Log out") }}
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- Mobile menu, show/hide based on menu state. -->
    <div class="sm:hidden" id="mobile-menu">
      <div class="px-2 pt-2 pb-3 space-y-1">
        <!-- Current: "bg-gray-900 text-white", Default: "text-gray-300 hover:bg-gray-700 hover:text-white" -->
        <a
          href="#"
          class="
            bg-gray-900
            text-white
            block
            px-3
            py-2
            rounded-md
            text-base
            font-medium
          "
          aria-current="page"
          >Dashboard</a
        >

        <a
          href="#"
          class="
            text-gray-300
            hover:bg-gray-700 hover:text-white
            block
            px-3
            py-2
            rounded-md
            text-base
            font-medium
          "
          >Team</a
        >

        <a
          href="#"
          class="
            text-gray-300
            hover:bg-gray-700 hover:text-white
            block
            px-3
            py-2
            rounded-md
            text-base
            font-medium
          "
          >Projects</a
        >

        <a
          href="#"
          class="
            text-gray-300
            hover:bg-gray-700 hover:text-white
            block
            px-3
            py-2
            rounded-md
            text-base
            font-medium
          "
          >Calendar</a
        >
      </div>
    </div>
  </nav>
</template>

<script lang="ts">
import Logo from "@/components/Logo.vue";
import { GraphQLError } from "graphql";
import { loadLanguageAsync } from "@/utils/i18n";
import { CURRENT_USER_CLIENT, USER_SETTINGS } from "../graphql/user";
import { changeIdentity, logout } from "../utils/auth";
import {
  CURRENT_ACTOR_CLIENT,
  IDENTITIES,
  UPDATE_DEFAULT_ACTOR,
} from "../graphql/actor";
import { displayName, IPerson, Person } from "../types/actor";
import { CONFIG } from "../graphql/config";
import { IConfig } from "../types/config.model";
import { ICurrentUser, IUser } from "../types/current-user.model";
import SearchField from "./SearchField.vue";
import RouteName from "../router/name";
import { defineComponent } from "vue-demi";
import {
  useApolloClient,
  useMutation,
  useQuery,
  useResult,
} from "@vue/apollo-composable";
import { ref } from "vue";
import { ICurrentUserRole } from "@/types/enums";

export default defineComponent({
  name: "NavBar",
  setup() {
    const { result: resultCurrentUser } = useQuery(CURRENT_USER_CLIENT);
    const currentUser =
      useResult<{ currentUser: ICurrentUser }>(resultCurrentUser);

    const { result: resultCurrentActor } = useQuery(CURRENT_ACTOR_CLIENT);
    const currentActor =
      useResult<{ currentUser: IPerson }>(resultCurrentActor);

    const { mutate: updateDefaultActor } = useMutation(UPDATE_DEFAULT_ACTOR);

    const { result: configResult } = useQuery(CONFIG);
    const config = useResult<{ config: IConfig }>(configResult);

    const { result: loggedUserResult } = useQuery(USER_SETTINGS);
    const loggedUser = useResult<{ config: IUser }>(loggedUserResult);

    const { result: identitiesResult } = useQuery(IDENTITIES);
    const identities = useResult<{ identities: IPerson[] }, [], Person[]>(
      identitiesResult,
      [],
      (data) => data.identities.map((identity: IPerson) => new Person(identity))
    );

    const mobileNavbarActive = false;

    const userDropDownOpened = ref(false);

    const { resolveClient } = useApolloClient();

    return {
      currentUser,
      currentActor,
      config,
      loggedUser,
      identities,
      mobileNavbarActive,
      userDropDownOpened,
      updateDefaultActor,
      RouteName,
      displayName,
      ICurrentUserRole,
      resolveClient,
    };
  },
  components: {
    Logo,
    SearchField,
  },
  methods: {
    toggleMenu(): void {
      this.userDropDownOpened = !this.userDropDownOpened;
    },
    async handleErrors(errors: GraphQLError[]): Promise<void> {
      if (
        errors.length > 0 &&
        errors[0].message ===
          "You need to be logged-in to view your list of identities"
      ) {
        await this.logout();
      }
    },
    async logout(): Promise<void> {
      await logout(this.resolveClient());
      // this.$oruga.notification.open({
      //   message: this.$t("You have been disconnected") as string,
      //   type: "is-success",
      //   position: "is-bottom-right",
      //   duration: 5000,
      // });

      if (this.$route.name === RouteName.HOME) return;
      await this.$router.push({ name: RouteName.HOME });
    },
    async setIdentity(identity: IPerson): Promise<void> {
      await this.updateDefaultActor({
        preferredUsername: identity.preferredUsername,
      });
      return changeIdentity(this.resolveClient(), identity);
    },
  },
  watch: {
    async currentActor(): Promise<void> {
      if (!this.currentUser?.isLoggedIn) return;

      // If we don't have any identities, the user has validated their account,
      // is logging for the first time but didn't create an identity somehow
      if (this.identities?.length === 0) {
        try {
          await this.$router.push({
            name: RouteName.REGISTER_PROFILE,
            params: {
              email: this.currentUser.email,
              userAlreadyActivated: "true",
            },
          });
        } catch (err) {
          return undefined;
        }
      }
    },
    loggedUser(): void {
      if (this.loggedUser?.locale) {
        console.debug("Setting locale from navbar");
        loadLanguageAsync(this.loggedUser.locale);
      }
    },
  },
  computed: {
    hideCreateEventsButton(): boolean {
      return !!this.config?.restrictions?.onlyGroupsCanCreateEvents;
    },
  },
});
</script>
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
nav {
  .navbar-item {
    a.button {
      font-weight: bold;
    }

    svg {
      height: 1.75rem;
    }
  }

  .navbar-dropdown .navbar-item {
    cursor: pointer;

    span {
      display: flex;
    }

    &.is-active {
      background: $secondary;
    }

    span.icon.is-medium {
      display: flex;
    }

    img {
      max-height: 2.5em;
    }
  }

  .navbar-item.has-dropdown a.navbar-link figure {
    @include margin-right(0.75rem);
    display: flex;
    align-items: center;
  }

  a.navbar-item:focus-within {
    background-color: inherit;
  }

  .koena {
    padding-top: 0;
    padding-bottom: 0;
    & > img {
      max-height: 4rem;
      padding-top: 0.2rem;
    }
  }

  .identity-wrapper {
    display: flex;

    .media-content span {
      display: flex;
      color: $violet-2;
    }
  }
}
</style>
