import { defineStore } from 'pinia'
import {
  AbilitiesType,
  Historical,
  BaseOrganizationProfile,
  BaseAccessProfile,
  OrignalAccessProfile,
} from "~/types/interfaces";

import {computed, ref, Ref} from "@vue/reactivity";
import {useOrganizationProfileStore} from "~/stores/organizationProfile";
import RoleUtils from "~/services/rights/roleUtils";

export const useAccessProfileStore = defineStore('accessProfile', () => {

  // State
  const bearer: Ref<string | null> = ref(null)
  const id: Ref<number | null> = ref(null)
  const switchId: Ref<number | null> = ref(null)
  const name: Ref<string | null> = ref(null)
  const givenName: Ref<string | null> = ref(null)
  const gender: Ref<string | null> = ref(null)
  const avatarId: Ref<number | null> = ref(null)
  const activityYear: Ref<number | null> = ref(null)
  const historical: Ref<Historical> = ref({
    "future": false,
    "past": false,
    "present": true,
  })
  const roles: Ref<Array<string>> = ref([])
  const abilities: Ref<Array<AbilitiesType>> = ref([])
  const isAdminAccess: Ref<boolean | null> = ref(false)
  const isSuperAdminAccess: Ref<boolean | null> = ref(false)
  const isAdmin: Ref<boolean | null> = ref(false)
  const isAdministratifManager: Ref<boolean | null> = ref(false)
  const isPedagogicManager: Ref<boolean | null> = ref(false)
  const isFinancialManager: Ref<boolean | null> = ref(false)
  const isCaMember: Ref<boolean | null> = ref(false)
  const isStudent: Ref<boolean | null> = ref(false)
  const isTeacher: Ref<boolean | null> = ref(false)
  const isMember: Ref<boolean | null> = ref(false)
  const isOther: Ref<boolean | null> = ref(false)
  const isGuardian: Ref<boolean | null> = ref(false)
  const isPayer: Ref<boolean | null> = ref(false)
  const multiAccesses: Ref<Array<BaseOrganizationProfile>> = ref([])
  const familyAccesses: Ref<Array<BaseAccessProfile>> = ref([])
  const originalAccess: Ref<OrignalAccessProfile | null> = ref(null)

  // Getters
  /**
   * Est-ce que l'utilisateur possède un compte administrateur
   * @return {boolean}
   */
  const isAdminAccount = computed((): boolean => {
    return isAdminAccess.value ?? false
  })

  /**
   * Retourne l'id de la session en cours
   * @return {boolean}
   */
  const currentAccessId = computed((): number => {
    return switchId.value ?? (id.value ?? 0)
  })

  // Actions
  const setMultiAccesses = (organizations: any) => {
    useEach(organizations, (organization: BaseOrganizationProfile) => {
      multiAccesses.value.push({
        id: organization.id,
        name: organization.name
      })
    })
  }

  const setFamilyAccesses = (accesses: any) => {
    useEach(accesses, (access: BaseAccessProfile) => {
      const a: BaseAccessProfile = {
        id: access.id,
        name: access.name,
        givenName: access.givenName,
        gender: access.gender,
        avatarId: access.avatarId
      }
      familyAccesses.value.push(a)
    })
  }

  /**
   * Est-ce que l'utilisateur possède le rôle donné ?
   *
   * @return {boolean}
   * @param role
   */
  const hasRole = (role: string): boolean => {
    return roles.value.includes(role)
  }

  const setProfile = (profile: any) => {
    const profileRoles: Array<string> = Object.values(profile.roles)

    name.value = profile.name
    givenName.value = profile.givenName
    gender.value = profile.gender
    avatarId.value = profile.avatarId
    activityYear.value = profile.activityYear
    historical.value = profile.historical
    isAdminAccess.value = profile.isAdminAccess

    isAdmin.value = RoleUtils.isA('ADMIN', profileRoles)
    isAdministratifManager.value = RoleUtils.isA('ADMINISTRATIF_MANAGER', profileRoles)
    isPedagogicManager.value = RoleUtils.isA('PEDAGOGICS_MANAGER', profileRoles)
    isFinancialManager.value = RoleUtils.isA('FINANCIAL_MANAGER', profileRoles)
    isCaMember.value = RoleUtils.isA('CA', profileRoles)
    isStudent.value = RoleUtils.isA('STUDENT', profileRoles)
    isTeacher.value = RoleUtils.isA('TEACHER', profileRoles)
    isMember.value = RoleUtils.isA('MEMBER', profileRoles)
    isOther.value = RoleUtils.isA('OTHER', profileRoles)
    isGuardian.value = profile.isGuardian
    isPayer.value = profile.isPayor
    roles.value = RoleUtils.filterFunctionRoles(profileRoles)

    // Time to add the original Access (switch User case)
    originalAccess.value = profile.originalAccess

    // Time to set Multi Accesses
    setMultiAccesses(profile.multiAccesses)

    // Time to set Family Accesses
    setFamilyAccesses(profile.familyAccesses)

    // Time to set Organization Profile
    const organizationProfile = useOrganizationProfileStore()
    organizationProfile.setProfile(profile.organization)
  }

  const refreshProfile = (profile: any) => {
    name.value = profile.name
    givenName.value = profile.givenName
    gender.value = profile.gender
    avatarId.value = profile.avatarId
    activityYear.value = profile.activityYear

    const organizationProfileStore = useOrganizationProfileStore()
    organizationProfileStore.refreshProfile(profile.organization)
  }

  const setOriginalAccess = (access: any) => {
    if (access) {
      const organization: BaseOrganizationProfile = {
        id: access.organization.id,
        name: access.organization.name
      }

      const originalAccess: OrignalAccessProfile = {
        id: access.id,
        name: access.name,
        givenName: access.givenName,
        gender: access.gender,
        isSuperAdminAccess: access.isSuperAdminAccess,
        avatarId: access.avatarId,
        organization: organization
      }
      setOriginalAccess(originalAccess)
    }
  }

  const setHistorical = (past: boolean, present: boolean, future: boolean) => {
    historical.value = <Historical> {
      past,
      present,
      future
    }
  }

  const setHistoricalRange = (dateStart: string, dateEnd: string) => {
    historical.value = <Historical> {
      past: false,
      present: false,
      future: false,
      dateStart,
      dateEnd
    }
  }

  return {
    bearer,
    id,
    switchId,
    name,
    givenName,
    gender,
    avatarId,
    activityYear,
    historical,
    roles,
    abilities,
    isAdminAccess,
    isSuperAdminAccess,
    isAdmin,
    isAdministratifManager,
    isPedagogicManager,
    isFinancialManager,
    isCaMember,
    isStudent,
    isTeacher,
    isMember,
    isOther,
    isGuardian,
    isPayer,
    multiAccesses,
    familyAccesses,
    originalAccess,
    isAdminAccount,
    currentAccessId,
    setMultiAccesses,
    setFamilyAccesses,
    setProfile,
    refreshProfile,
    setOriginalAccess,
    setHistorical,
    setHistoricalRange
  }
})
