import { computed } from 'vue'

export function useAdminUsers({
  api,
  auth,
  users,
  userQuery,
  userSort,
  userSortDirection,
  userAvatarInputs,
  modalTargetUser,
  modalPasswordDraft,
  modalRoleNextAdmin,
  modalUserDraftEmail,
  modalUserDraftNickname,
  modalUserDraftIsAdmin,
  userEditModalOpen,
  userPasswordModalOpen,
  userDeleteModalOpen,
  userRoleModalOpen,
  resetMessages,
  refreshUsers,
  success,
  error,
}) {
  function setUserAvatarInput(userId, el) {
    if (!userId) return
    if (!el) {
      delete userAvatarInputs.value[userId]
      return
    }
    userAvatarInputs.value[userId] = el
  }

  const canManageModalRole = computed(() => {
    if (!auth.user?.isPrimaryAdmin) return false
    if (!modalTargetUser.value) return false
    return !modalTargetUser.value.isPrimaryAdmin
  })

  function canManageUser(user) {
    if (!user?.isPrimaryAdmin) return true
    return !!auth.user?.isPrimaryAdmin
  }

  function canEditUserAvatar(user) {
    return canManageUser(user)
  }

  function canEditUserInfo(user) {
    return canManageUser(user)
  }

  function canResetUserPassword(user) {
    return canManageUser(user)
  }

  function canDeleteUser(user) {
    if (!canManageUser(user)) return false
    if (user?.isAdmin && !auth.user?.isPrimaryAdmin) return false
    return user?.id !== auth.user?.id
  }

  const isUserEditDirty = computed(() => {
    if (!modalTargetUser.value) return false
    return (
      modalUserDraftEmail.value.trim() !== (modalTargetUser.value.email || '') ||
      modalUserDraftNickname.value.trim() !== (modalTargetUser.value.nickname || '') ||
      !!modalUserDraftIsAdmin.value !== !!modalTargetUser.value.isAdmin
    )
  })

  function roleLabelOf(user) {
    if (user?.isPrimaryAdmin) return '최고 관리자'
    if (user?.isAdmin) return '운영자'
    return '일반 회원'
  }

  function openUserAvatarPicker(user) {
    if (!canEditUserAvatar(user)) return
    userAvatarInputs.value[user?.id]?.click()
  }

  async function uploadUserAvatar(user, file, { remove = false } = {}) {
    resetMessages()
    if (!user?.id) return

    try {
      user.isAvatarBusy = true
      const data = await api.updateAdminUserAvatar(user.id, { file, removeAvatar: remove })
      const updated = data.user
      users.value = users.value.map((entry) =>
        entry.id === updated.id
          ? {
              ...entry,
              ...updated,
              isAvatarBusy: false,
            }
          : entry
      )
      if (modalTargetUser.value?.id === updated.id) {
        modalTargetUser.value = { ...modalTargetUser.value, ...updated }
      }
      if (updated.id === auth.user?.id) await auth.refresh()
      await refreshUsers()
      success.value = remove ? '회원 썸네일을 삭제했어요.' : '회원 썸네일을 업데이트했어요.'
    } catch (e) {
      error.value = remove ? '회원 썸네일 삭제에 실패했어요.' : '회원 썸네일 변경에 실패했어요.'
    } finally {
      const target = users.value.find((entry) => entry.id === user.id)
      if (target) target.isAvatarBusy = false
    }
  }

  async function onUserAvatarChange(user, event) {
    const file = event.target.files && event.target.files[0] ? event.target.files[0] : null
    event.target.value = ''
    if (!file) return
    await uploadUserAvatar(user, file)
  }

  async function removeUserAvatar(user) {
    if (!canEditUserAvatar(user)) return
    if (!user?.avatarSrc) return
    await uploadUserAvatar(user, null, { remove: true })
  }

  function openUserEditModal(user) {
    if (!canEditUserInfo(user)) return
    resetMessages()
    modalTargetUser.value = user ? { ...user } : null
    modalUserDraftEmail.value = user?.email || ''
    modalUserDraftNickname.value = user?.nickname || ''
    modalUserDraftIsAdmin.value = !!user?.isAdmin
    userEditModalOpen.value = true
  }

  function closeUserEditModal() {
    userEditModalOpen.value = false
    modalTargetUser.value = null
    modalUserDraftEmail.value = ''
    modalUserDraftNickname.value = ''
    modalUserDraftIsAdmin.value = false
  }

  async function saveUserEdit() {
    resetMessages()
    if (!modalTargetUser.value?.id) return

    try {
      const data = await api.updateAdminUser(modalTargetUser.value.id, {
        email: modalUserDraftEmail.value.trim(),
        nickname: modalUserDraftNickname.value.trim(),
        isAdmin: !!modalUserDraftIsAdmin.value,
      })
      const updated = data.user
      users.value = users.value.map((entry) =>
        entry.id === updated.id
          ? {
              ...entry,
              ...updated,
              isAvatarBusy: entry.isAvatarBusy || false,
            }
          : entry
      )
      if (updated.id === auth.user?.id) await auth.refresh()
      closeUserEditModal()
      await refreshUsers()
      success.value = '회원 정보를 저장했어요.'
    } catch (e) {
      error.value = '회원 정보 저장에 실패했어요.'
    }
  }

  function openUserPasswordModal(user) {
    if (!canResetUserPassword(user)) return
    resetMessages()
    modalTargetUser.value = user ? { ...user } : null
    modalPasswordDraft.value = ''
    userPasswordModalOpen.value = true
  }

  function closeUserPasswordModal() {
    userPasswordModalOpen.value = false
    modalTargetUser.value = null
    modalPasswordDraft.value = ''
  }

  function userDisplayName(user) {
    return user?.nickname || user?.email?.split('@')[0] || '알 수 없음'
  }

  async function confirmUserPasswordReset() {
    resetMessages()
    if (!modalTargetUser.value?.id) return

    const password = modalPasswordDraft.value.trim()
    if (!password) {
      error.value = '초기화할 비밀번호를 입력해주세요.'
      return
    }

    try {
      await api.updateAdminUserPassword(modalTargetUser.value.id, { password })
      success.value = `${userDisplayName(modalTargetUser.value)} 계정 비밀번호를 초기화했어요.`
      closeUserPasswordModal()
    } catch (e) {
      error.value = '비밀번호 초기화에 실패했어요.'
    }
  }

  function openUserDeleteModal(user) {
    if (!canDeleteUser(user)) return
    resetMessages()
    modalTargetUser.value = user ? { ...user } : null
    userDeleteModalOpen.value = true
  }

  function closeUserDeleteModal() {
    userDeleteModalOpen.value = false
    modalTargetUser.value = null
  }

  async function confirmUserDelete() {
    resetMessages()
    if (!modalTargetUser.value?.id) return

    try {
      const deletingSelf = modalTargetUser.value.id === auth.user?.id
      const deletedName = userDisplayName(modalTargetUser.value)
      await api.deleteAdminUser(modalTargetUser.value.id)
      users.value = users.value.filter((entry) => entry.id !== modalTargetUser.value.id)
      closeUserDeleteModal()
      success.value = `${deletedName} 계정을 삭제했어요.`
      if (deletingSelf) await auth.refresh()
    } catch (e) {
      error.value = '회원 삭제에 실패했어요.'
    }
  }

  function openUserRoleModal(user, nextIsAdmin = !modalUserDraftIsAdmin.value) {
    resetMessages()
    modalTargetUser.value = user ? { ...user } : null
    modalRoleNextAdmin.value = !!nextIsAdmin
    userRoleModalOpen.value = true
  }

  function closeUserRoleModal() {
    userRoleModalOpen.value = false
    if (!userEditModalOpen.value) modalTargetUser.value = null
    modalRoleNextAdmin.value = false
  }

  function confirmUserRoleDraft() {
    if (!modalTargetUser.value?.id) return
    modalUserDraftIsAdmin.value = modalRoleNextAdmin.value
    const targetLabel = modalRoleNextAdmin.value ? '운영자 권한을 저장 대기 상태로 반영했어요.' : '운영자 권한 해제를 저장 대기 상태로 반영했어요.'
    closeUserRoleModal()
    success.value = targetLabel
  }

  function submitUserFilters() {
    refreshUsers({
      q: userQuery.value,
      sort: userSort.value,
      direction: userSortDirection.value,
    })
  }

  return {
    setUserAvatarInput,
    canManageModalRole,
    canEditUserAvatar,
    canEditUserInfo,
    canResetUserPassword,
    canDeleteUser,
    isUserEditDirty,
    roleLabelOf,
    openUserAvatarPicker,
    onUserAvatarChange,
    removeUserAvatar,
    openUserEditModal,
    closeUserEditModal,
    saveUserEdit,
    openUserPasswordModal,
    closeUserPasswordModal,
    confirmUserPasswordReset,
    openUserDeleteModal,
    closeUserDeleteModal,
    confirmUserDelete,
    openUserRoleModal,
    closeUserRoleModal,
    confirmUserRoleDraft,
    submitUserFilters,
    userDisplayName,
  }
}
