<script setup lang="ts">
import { AuthenticationAPIClient, type User, type UserUpdatePayload } from '@/api/auth';
import { useAuthStore } from '@/stores/auth';
import { onMounted, ref, useTemplateRef, watch, type Ref } from 'vue';
import ConfirmDialog from './ConfirmDialog.vue';
import { useRouter } from 'vue-router';


const authStore = useAuthStore()
const router = useRouter()
const apiClient = new AuthenticationAPIClient(authStore)

const users: Ref<User[]> = ref([])
const usersPage: Ref<number> = ref(0)
const usersPageSize: Ref<number> = ref(50)
const loading: Ref<boolean> = ref(true)

const deleteUserConfirmDialog = useTemplateRef('deleteUserConfirmDialog')

onMounted(() => {
  watch([usersPage, usersPageSize], fetchUsers)
  fetchUsers()
})

function fetchUsers() {
  loading.value = true
  apiClient.getUsers(usersPage.value, usersPageSize.value).handleErrorsWithAlert()
    .then(result => {
      if (result !== null) {
        users.value = result
      }
    })
    .finally(() => loading.value = false)
}

async function deleteUser(user: User) {
  const confirm = await deleteUserConfirmDialog.value?.show()
  if (!confirm) return
  await apiClient.deleteUser(user.id).handleErrorsWithAlert()
  fetchUsers() // Refresh the list of users.
}

async function toggleLocked(user: User) {
  const payload: UserUpdatePayload = {
    isLocked: !user.isLocked
  }
  await apiClient.updateUser(user.id, payload).handleErrorsWithAlert()
  fetchUsers()
}

function viewAsUser(user: User) {
  if (!authStore.state) return
  authStore.state.adminAsUser = user
  router.replace('/')
}

function booleanCellClass(b: boolean) {
  return {
    'color-false': !b,
    'color-true': b,
    'text-mono': true
  }
}

defineExpose({ fetchUsers })

</script>
<template>
  <div>
    <h3 style="margin-bottom: 0.25em;">Users</h3>
    <div class="button-bar">
      <button type="button" :disabled="loading || usersPage < 1" @click="usersPage -= 1">Previous Page</button>
      <span>Page: {{ usersPage + 1 }}</span>
      <button type="button" @click="usersPage += 1" :disabled="loading">Next Page</button>
      <label style="display: inline;">Page Size:</label>
      <select v-model="usersPageSize" :disabled="loading">
        <option value="5">5</option>
        <option value="10">10</option>
        <option value="50" selected>50</option>
        <option value="100">100</option>
      </select>
    </div>
    <table class="users-table">
      <thead>
        <tr>
          <th>ID</th>
          <th>Username</th>
          <th>Created At</th>
          <th>Admin</th>
          <th>Locked</th>
          <th>Actions</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="user in users" :key="user.id">
          <td class="text-mono">{{ user.id }}</td>
          <td>{{ user.username }}</td>
          <td>{{ new Date(user.createdAt).toLocaleString() }}</td>
          <td :class="booleanCellClass(user.isAdmin)">{{ user.isAdmin }}
          </td>
          <td :class="booleanCellClass(user.isLocked)">{{ user.isLocked
            }}</td>
          <td>
            <div>
              <button type="button" @click="deleteUser(user)">Delete</button>
              <button type="button" @click="toggleLocked(user)" v-text="user.isLocked ? 'Unlock' : 'Lock'"></button>
              <button type="button" @click="viewAsUser(user)" v-if="user.id !== authStore.state?.user.id">View
                as</button>
            </div>
          </td>
        </tr>
      </tbody>
    </table>

    <ConfirmDialog ref="deleteUserConfirmDialog">
      <p>
        Are you sure you want to delete this user?
      </p>
    </ConfirmDialog>
  </div>
</template>
<style scoped>
.users-table {
  border-collapse: collapse;
}

.users-table th,
td {
  border: 1px solid gray;
  padding: 0.5em;
}

.color-false {
  color: red;
}

.color-true {
  color: lime;
}
</style>
