import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
import { api } from 'boot/axios'
import { useProjectsStore } from 'stores/projects'
import type { User, UserParams } from 'types/User'

export const useUsersStore = defineStore('users', () => {
  const projectsStore = useProjectsStore()
  const users = ref<User[]>([])
  const isInit = ref<boolean>(false)
  const isLoading = ref(false)

  const currentProjectId = computed(() => projectsStore.currentProjectId)
  
  async function init () {
    // guard for double request
    if (isLoading.value) return
    isLoading.value = true
    try {
      reset()
      const { data } = await api.get(`/project/${currentProjectId.value}/user`)
      users.value = [...data.data.map((user: User) => ({
        ...user,
        displayName: getDisplayName(user)
      }))]
      isInit.value = true
    } catch {
      reset()
    } finally {
      isLoading.value = false
    }
  }

  function reset () {
    users.value = []
    isInit.value = false
  }
  
  async function update (userId: number, userData: UserParams) {
    const { data } = await api.put(`/project/${currentProjectId.value}/user/${userId}`, userData)
    const userAPI = data.data
    const idx = users.value.findIndex(item => item.id === userAPI.id)
    if (idx !== -1) users.value[idx] = { ...users.value[idx], ...userAPI }
  }

  async function blockUser (userId: number) {
    const { data } = await api.post(`/project/${currentProjectId.value}/user/${userId}/block`)
    if (data.success) {
      const idx = users.value.findIndex(item => item.id === userId)
      if (users.value[idx]) Object.assign(users.value[idx], { is_blocked: true })
    }
  }

  async function unblockUser (userId: number) {
    const { data } = await api.post(`/project/${currentProjectId.value}/user/${userId}/unblock`)
    if (data.success) {
      const idx = users.value.findIndex(item => item.id === userId)
      if (users.value[idx]) Object.assign(users.value[idx], { is_blocked: false })
    }
  }

  function userById (id: number) {
    return users.value.find(el => el.id === id)
  }

  function userNameById (id: number) {
    const user = userById(id)
    return String(user?.displayName || (user ? getDisplayName(user) : '---'))
  }

  // Internal function
  function getDisplayName (user: User): string {
    return user.fullname
    || [user.firstname, user.lastname].filter(Boolean).join(' ').trim()
    || user.username
    || '---'
  }

  return {
    users,
    isInit,
    init,
    reset,
    update,
    blockUser,
    unblockUser,
    userById,
    userNameById
  }
})
