<template>
  <div class="p-6">
    <h2 class="kestrel-page-heading mb-2">
      Members
    </h2>
    <p
      v-if="!user"
      class="text-sm text-kestrel-muted"
    >
      Sign in to view members.
    </p>
    <p
      v-else-if="!canEditPois"
      class="text-sm text-kestrel-muted"
    >
      You don't have access to the members list.
    </p>
    <template v-else>
      <p
        v-if="isAdmin"
        class="mb-3 text-xs text-kestrel-muted"
      >
        Only admins can change roles and manage local users. OIDC users are managed via your identity provider.
      </p>
      <div
        v-if="isAdmin"
        class="mb-3 flex justify-start"
      >
        <button
          type="button"
          class="rounded border border-kestrel-accent bg-kestrel-accent/10 px-3 py-1.5 text-sm font-medium text-kestrel-accent hover:bg-kestrel-accent-dim"
          @click="openAddUserModal"
        >
          Add user
        </button>
      </div>
      <MembersTable
        :users="users"
        :role-by-user-id="roleByUserId"
        :role-options="roleOptions"
        :is-admin="isAdmin"
        :current-user-id="user?.id ?? null"
        :open-role-dropdown-id="openRoleDropdownId"
        @toggle-role-dropdown="toggleRoleDropdown"
        @close-role-dropdown="openRoleDropdownId = null"
        @select-role="selectRole"
        @save-role="saveRole"
        @edit-user="openEditUser"
        @delete-confirm="openDeleteConfirm"
      />
      <!-- Add user modal -->
      <AddUserModal
        :show="addUserModalOpen"
        :submit-error="createError"
        @close="closeAddUserModal"
        @submit="onAddUserSubmit"
      />
      <DeleteUserConfirmModal
        :user="deleteConfirmUser"
        @close="deleteConfirmUser = null"
        @confirm="confirmDeleteUser"
      />
      <EditUserModal
        :user="editUserModal"
        :submit-error="editError"
        @close="editUserModal = null"
        @submit="onEditUserSubmit"
      />
    </template>
  </div>
</template>

<script setup>
const { user, isAdmin, canEditPois, refresh: refreshUser } = useUser()

const { data: usersData, refresh: refreshUsers } = useAsyncData(
  'users',
  () => $fetch('/api/users').catch(() => []),
  { default: () => [] },
)
const users = computed(() => Object.freeze([...(usersData.value ?? [])]))

const roleOptions = ['admin', 'leader', 'member']
const pendingRoleUpdates = ref({})
const roleByUserId = computed(() => {
  const base = Object.fromEntries(users.value.map(u => [u.id, u.role]))
  return { ...base, ...pendingRoleUpdates.value }
})
const openRoleDropdownId = ref(null)

const addUserModalOpen = ref(false)
const createError = ref('')
const editUserModal = ref(null)
const editError = ref('')
const deleteConfirmUser = ref(null)

watch(user, () => {
  if (canEditPois.value) refreshUsers()
}, { immediate: true })

function toggleRoleDropdown(userId) {
  openRoleDropdownId.value = openRoleDropdownId.value === userId ? null : userId
}

function selectRole(userId, role) {
  pendingRoleUpdates.value = { ...pendingRoleUpdates.value, [userId]: role }
  openRoleDropdownId.value = null
}

async function saveRole(id) {
  const role = roleByUserId.value[id]
  if (!role) return
  try {
    await $fetch(`/api/users/${id}`, { method: 'PATCH', body: { role } })
    await refreshUsers()
    pendingRoleUpdates.value = Object.fromEntries(
      Object.entries(pendingRoleUpdates.value).filter(([k]) => k !== id),
    )
  }
  catch {
    // could set error state
  }
}

function openAddUserModal() {
  addUserModalOpen.value = true
  createError.value = ''
}

function closeAddUserModal() {
  addUserModalOpen.value = false
  createError.value = ''
}

async function onAddUserSubmit(payload) {
  createError.value = ''
  try {
    await $fetch('/api/users', {
      method: 'POST',
      body: {
        identifier: payload.identifier,
        password: payload.password,
        role: payload.role,
      },
    })
    closeAddUserModal()
    await refreshUsers()
  }
  catch (e) {
    createError.value = e.data?.message || e.message || 'Failed to create user'
  }
}

function openEditUser(u) {
  editUserModal.value = u
  editError.value = ''
}

async function onEditUserSubmit(payload) {
  const u = editUserModal.value
  if (!u) return
  editError.value = ''
  const body = { identifier: payload.identifier.trim() }
  if (payload.password) body.password = payload.password
  try {
    await $fetch(`/api/users/${u.id}`, { method: 'PATCH', body })
    editUserModal.value = null
    await refreshUsers()
    await refreshUser()
  }
  catch (e) {
    editError.value = e.data?.message || e.message || 'Failed to update user'
  }
}

function openDeleteConfirm(u) {
  deleteConfirmUser.value = u
}

async function confirmDeleteUser() {
  const u = deleteConfirmUser.value
  if (!u) return
  try {
    await $fetch(`/api/users/${u.id}`, { method: 'DELETE' })
    deleteConfirmUser.value = null
    await refreshUsers()
  }
  catch (e) {
    alert(e.data?.message || e.message || 'Failed to remove user')
  }
}
</script>
