<template>
  <v-btn
      ref="btn"
      icon
      color=""
      @click="click"
  >
    <v-badge
        color="orange"
        offset-y="10"
        :value="unreadNotification.length > 0"
        :content="unreadNotification.length"
    >
      <v-icon class="text-ot-white" small>
        fa-bell
      </v-icon>
    </v-badge>
  </v-btn>

  <v-tooltip bottom :activator="btn">
    <span>{{ $t('notification') }}</span>
  </v-tooltip>

  <v-menu :activator="btn" offset-y v-model="isOpen">
    <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)" icon="mdi-download" />
              </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 text-ot-white" v-text="$t('all_notification')"/>
          </v-list-item>
        </template>
      </v-card-actions>
    </v-card>
  </v-menu>
</template>

<script setup lang="ts">
import {NOTIFICATION_TYPE, QUERY_TYPE} from "~/types/enum/enums";
import {Notification} from "~/models/Core/Notification";
import {NotificationUsers} from "~/models/Core/NotificationUsers";
import {useAccessProfileStore} from "~/stores/accessProfile";
import {ComputedRef, Ref} from "@vue/reactivity";
import {useEntityFetch} from "~/composables/data/useEntityFetch";
import {Pagination} from "~/types/data";

const accessProfileStore = useAccessProfileStore()
const currentAccessId = accessProfileStore.id
const loading: Ref<Boolean> = ref(true)
const isOpen: Ref<Boolean> = ref(false)
const page: Ref<number> = ref(1)

const i18n = useI18n()
const runtimeConfig = useRuntimeConfig()

const btn = ref(null)

const { fetchCollection } = useEntityFetch()

const { data: collection, pending } = await fetchCollection(Notification)

/**
 * On récupère les Notifications via le store
 */
const notifications: ComputedRef = computed(() => {
  // TODO: revoir pour reprendre le order by et tout
  return collection.value !== null ? collection.value.items : []
})

/**
 * Les metadata dépendront de la dernière valeur du GET lancé
 */
const pagination: ComputedRef<Pagination> = computed(() => {
  return collection.value !== null ? collection.value.pagination : {}
})

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

/**
 * 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')}`

     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')} `

    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 notifications 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(accessProfileStore.originalAccess)
    url_parts[0] = `api/${accessProfileStore.originalAccess.id}/${currentAccessId}`
  else
    url_parts[0] = `api/${currentAccessId}`

  window.open(`${runtimeConfig.baseUrlLegacy}/${url_parts.join('')}`);
}

const notificationUrl = `${runtimeConfig.baseURL_adminLegacy}/notifications/list/`

</script>

<style scoped lang="scss">
  #all_notifications{
    background: rgb(var(--v-theme-ot-green, white));
    color: white;
  }
  .list_item{
    white-space: normal;
  }
  .unread{
    background: #ecf0f5;
  }
</style>
