<template>
  <v-menu offset-y v-model="isOpen">
    <template #activator="{ on: { click }, attrs }">
      <v-tooltip bottom>
        <template #activator="{ on: on_tooltips , attrs: attrs_tooltips }">
          <v-btn
            icon
            v-bind="[attrs, attrs_tooltips]"
            color=""
            v-on="on_tooltips"
            @click="click"
          >
            <v-badge
              color="orange"
              offset-y="10"
              :value="unreadNotification.length > 0"
              :content="unreadNotification.length"
            >
              <v-icon class="ot_white--text" small>
                fa-bell
              </v-icon>
            </v-badge>
          </v-btn>
        </template>
        <span>{{ $t('notification') }}</span>
      </v-tooltip>
    </template>
    <v-card scrollable max-width="400">
      <v-card-title class="ot_header_menu text-body-2 font-weight-bold">
        {{ $t('notification') }}
      </v-card-title>
      <v-card-text class="ma-0 pa-0 header_menu">
        <v-list dense :subheader="true">
          <template v-for="(notification, index) in notifications">
            <v-list-item :key="index" :class="`${notification.notificationUsers.length === 0 ? 'unread' : ''}`">
              <v-list-item-content>
                <v-list-item-title class="list_item mt-2 mb-2" v-text="getMessage(notification)"/>
              </v-list-item-content>
              <v-list-item-icon v-if="notification.link" class="pt-4">
                <v-icon @click="download(notification.link)">mdi-download</v-icon>
              </v-list-item-icon>
            </v-list-item>
            <v-divider></v-divider>
          </template>
        </v-list>
        <v-card v-intersect="update"></v-card>
        <v-row
          v-if="loading"
          class="fill-height mt-3 mb-3"
          align="center"
          justify="center"
        >
          <v-progress-circular
            indeterminate
            color="grey lighten-1"
          ></v-progress-circular>
        </v-row>
      </v-card-text>
      <v-card-actions class="ma-0 pa-0">
        <template>
          <v-list-item
            id="all_notifications"
            :key="$t('all_notification')"
            :href="notificationUrl"
            router
          >
            <v-list-item-title class="text-body-2 ot_white--text" v-text="$t('all_notification')"/>
          </v-list-item>
        </template>
      </v-card-actions>
    </v-card>
  </v-menu>
</template>

<script lang="ts">
import {computed, ComputedRef, defineComponent, onUnmounted, Ref, ref, useContext, useFetch, watch} from '@nuxtjs/composition-api'
import {NOTIFICATION_TYPE, QUERY_TYPE} from "~/types/enums";
import {Notification} from "~/models/Core/Notification";
import {repositoryHelper} from "~/services/store/repository";
import {ApiResponse, HydraMetadata} from "~/types/interfaces";
import {queryHelper} from "~/services/store/query";
import {NotificationUsers} from "~/models/Core/NotificationUsers";
import {$accessProfile} from "~/services/profile/accessProfile";

export default defineComponent({
  setup: function () {
    const {$dataProvider, $dataPersister, $config, store, app: { i18n }} = useContext()
    const profileAccess = store.state.profile.access
    $accessProfile.setStore(store)
    const currentAccessId = $accessProfile.getCurrentAccessId()

    const loading: Ref<Boolean> = ref(true)
    const isOpen: Ref<Boolean> = ref(false)
    const page: Ref<number> = ref(1)
    const data: Ref<ApiResponse> = ref({} as ApiResponse)

    /**
     * On récupère les notifications via l'API qui seront stockées dans le store
     */
    const {fetch, fetchState} = useFetch(async () => {
      data.value = await $dataProvider.invoke({
        type: QUERY_TYPE.MODEL,
        model: Notification,
        listArgs: {
          itemsPerPage: 10,
          page: page.value
        }
      })
      loading.value = false
    })

    /**
     * On récupère les Notifications via le store
     */
    const notifications: ComputedRef = computed(() => {
      const query = repositoryHelper.getRepository(Notification).with('message').orderBy('id', 'desc')
      return queryHelper.getCollection(query)
    })

    /**
     * on calcul le nombre de notification non lues
     */
    const unreadNotification: ComputedRef<Array<Notification>> = computed(() => {
      return notifications.value.filter((notification: Notification) => {
        return notification.notificationUsers.length === 0
      })
    })

    /**
     * Les metadata dépendront de la dernière valeur du GET lancé
     */
    const metadata: ComputedRef<HydraMetadata> = computed(() => {
      return data.value.metadata
    })

    /**
     * Lorsque l'utilisateur scroll on regarde la nextPage a charger et on le fait que si le pending du fetch est false
     * (si on a fini de télécharger les éléments précédents)
     */
    const update = async () => {
      if (!fetchState.pending && metadata.value?.nextPage && metadata.value.nextPage > 0) {
        loading.value = true
        page.value = metadata.value.nextPage
        await fetch()
        //Si des notifications n'avaient pas été marquées comme lues, on le fait immédiatement.
        markNotificationsAsRead()
      }
    }

    /**
     * On construit le message qui va devoir s'afficher pour une notification
     * @param notification
     */
    const getMessage = (notification:Notification) => {
      switch (notification.type){
        case NOTIFICATION_TYPE.FILE :
         return `${i18n.t('your_file')} ${notification.message?.fileName} ${i18n.t('is_ready_to_be_downloaded')}`
          break;

         case NOTIFICATION_TYPE.MESSAGE:
           if(notification.message?.action)
             return `${i18n.t('your_message')} ${notification.message?.fileName} ${i18n.t('is_ready_to_be')} ${notification.message.action}`

           return `${i18n.t('your_message')} ${notification.message?.about ?? ''} ${i18n.t('has_been_sent')} `
           break;

        case NOTIFICATION_TYPE.SYSTEM :
          if(notification.message?.about)
            return `${i18n.t(notification.message.about)}`
          break;

        default:
          return i18n.t(notification.name)
      }
    }

    /**
     * Dès l'ouverture du menu, on indique que les notifications non lues, le sont.
     */
    const unwatch = watch(isOpen, (newValue, oldValue) => {
      if(newValue){
        markNotificationsAsRead()
      }
    })

    onUnmounted(() => {
      unwatch()
    })

    /**
     * Marque les notification non lues comme lues
     */
    const markNotificationsAsRead = () => {
      unreadNotification.value.map((notification:Notification)=>{
        notification.notificationUsers = ['read']
        repositoryHelper.persist(Notification, notification)
        createNewNotificationUsers(notification)
      })
    }

    /**
     * Créer une nouvelle notification users coté back.
     * @param notification
     */
    const createNewNotificationUsers = (notification: Notification) =>{
      const newNotificationUsers = repositoryHelper.persist(NotificationUsers, new NotificationUsers(
        {
          access:`/api/accesses/${currentAccessId}`,
          notification:`/api/notifications/${notification.id}`,
          isRead: true
        }
      )) as NotificationUsers

      $dataPersister.invoke({
        type: QUERY_TYPE.MODEL,
        model: NotificationUsers,
        idTemp: newNotificationUsers.id,
        showProgress: false
      })
    }

    /**
     * Download le lien
     * @param link
     */
    const download = (link: string) => {
      const url_parts: Array<string> = link.split('/api');
      if(profileAccess.originalAccess)
        url_parts[0] = `api/${profileAccess.originalAccess}/${currentAccessId}`
      else
        url_parts[0] = `api/${currentAccessId}`

      window.open(`${$config.baseURL_Legacy}/${url_parts.join('')}`);
    }

    return {
      data,
      getMessage,
      notificationUrl: `${$config.baseURL_adminLegacy}/notifications/list/`,
      loading,
      notifications,
      update,
      unreadNotification,
      isOpen,
      download
    }
  }
})
</script>

<style scoped>
  #all_notifications{
    background: var(--v-ot_green-base, white);
    color: white;
  }
  .list_item{
    white-space: normal;
  }
  .unread{
    background: #ecf0f5;
  }
</style>
