<template>
  <div class="h-full min-h-0 flex flex-col" data-testid="users-view">
    <AppHeader
      title="Users"
      description="Create accounts, update roles, and reset passwords for active staff."
    >
      <template #actions>
        <button
          type="button"
          class="btn-primary"
          data-testid="users-toggle-create"
          @click="showCreate = !showCreate"
        >
          {{ showCreate ? 'Cancel' : 'Create user' }}
        </button>
      </template>
    </AppHeader>

    <div class="flex-1 overflow-y-auto p-4 sm:p-6 lg:p-8">
      <div class="max-w-7xl mx-auto space-y-6">

        <section v-if="showCreate" class="card space-y-4" data-testid="users-create-form">
          <header>
            <h2 class="text-base font-semibold text-ink-strong">Create user</h2>
            <p class="text-sm text-ink-secondary mt-1">
              Password must be at least 8 characters with one uppercase letter and one digit.
            </p>
          </header>

          <form class="grid gap-4 sm:grid-cols-2" @submit.prevent="submitCreate">
            <div>
              <label for="create-username" class="block text-sm font-semibold text-ink mb-2">
                Username
              </label>
              <input
                id="create-username"
                v-model="createForm.username"
                type="text"
                class="form-input"
                autocomplete="off"
                required
                maxlength="50"
              />
            </div>
            <div>
              <label for="create-fullname" class="block text-sm font-semibold text-ink mb-2">
                Full name
              </label>
              <input
                id="create-fullname"
                v-model="createForm.fullName"
                type="text"
                class="form-input"
                required
                maxlength="200"
              />
            </div>
            <div>
              <label for="create-role" class="block text-sm font-semibold text-ink mb-2">
                Role
              </label>
              <select id="create-role" v-model="createForm.role" class="form-input" required>
                <option v-for="role in ROLE_OPTIONS" :key="role" :value="role">
                  {{ formatRole(role) }}
                </option>
              </select>
            </div>
            <div>
              <label for="create-password" class="block text-sm font-semibold text-ink mb-2">
                Temporary password
              </label>
              <input
                id="create-password"
                v-model="createForm.password"
                type="password"
                class="form-input"
                autocomplete="new-password"
                required
                minlength="8"
              />
            </div>
            <div class="sm:col-span-2 flex flex-wrap items-center gap-3">
              <button type="submit" class="btn-primary" :disabled="creating">
                {{ creating ? 'Creating…' : 'Create user' }}
              </button>
              <p v-if="createError" class="text-sm text-clinical-danger" role="alert">
                {{ createError }}
              </p>
            </div>
          </form>
        </section>

        <section class="card space-y-4">
          <div class="flex flex-wrap items-end justify-between gap-3">
            <header>
              <h2 class="text-base font-semibold text-ink-strong">Active users</h2>
              <p class="text-sm text-ink-secondary mt-1">
                Deactivated users are removed from this list.
              </p>
            </header>
            <div class="min-w-[12rem]">
              <label for="role-filter" class="block text-sm font-semibold text-ink mb-2">
                Filter by role
              </label>
              <select
                id="role-filter"
                v-model="roleFilter"
                class="form-input"
                data-testid="users-role-filter"
                @change="loadUsers"
              >
                <option value="">All roles</option>
                <option v-for="role in ROLE_OPTIONS" :key="role" :value="role">
                  {{ formatRole(role) }}
                </option>
              </select>
            </div>
          </div>

          <InlineError
            v-if="usersStore.error"
            title="Could not load users"
            :message="usersStore.error"
            retry-label="Retry"
            @retry="loadUsers"
          />
          <SkeletonBlock v-else-if="usersStore.loading" variant="table" :rows="6" />
          <EmptyState
            v-else-if="usersStore.users.length === 0"
            title="No users found."
            description="Create a user or clear the role filter."
          />
          <div v-else class="overflow-x-auto">
            <table class="w-full min-w-[36rem] text-sm">
              <thead>
                <tr class="border-b border-line text-left text-ink-secondary">
                  <th class="py-2 px-3 font-medium">Full name</th>
                  <th class="py-2 px-3 font-medium">Username</th>
                  <th class="py-2 px-3 font-medium">Role</th>
                  <th class="py-2 px-3 font-medium text-right">Actions</th>
                </tr>
              </thead>
              <tbody>
                <tr
                  v-for="user in usersStore.users"
                  :key="user.id"
                  class="border-b border-line last:border-0"
                  :data-testid="`user-row-${user.username}`"
                >
                  <td class="py-3 px-3 text-ink-strong font-medium">{{ user.fullName }}</td>
                  <td class="py-3 px-3 font-mono text-xs text-ink">{{ user.username }}</td>
                  <td class="py-3 px-3 text-ink">{{ formatRole(user.role) }}</td>
                  <td class="py-3 px-3">
                    <div class="flex flex-wrap justify-end gap-2">
                      <button
                        type="button"
                        class="text-sm font-medium text-primary-700 hover:text-primary-800"
                        @click="startEdit(user)"
                      >
                        Edit
                      </button>
                      <button
                        type="button"
                        class="text-sm font-medium text-primary-700 hover:text-primary-800"
                        data-testid="users-reset-password"
                        @click="openReset(user)"
                      >
                        Reset password
                      </button>
                      <button
                        type="button"
                        class="text-sm font-medium text-clinical-danger hover:opacity-80"
                        data-testid="users-deactivate"
                        @click="deactivateUser(user)"
                      >
                        Deactivate
                      </button>
                    </div>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </section>

        <section v-if="editingUser" class="card space-y-4" data-testid="users-edit-form">
          <header>
            <h2 class="text-base font-semibold text-ink-strong">
              Edit {{ editingUser.fullName }}
            </h2>
            <p class="text-sm text-ink-secondary mt-1 font-mono">{{ editingUser.username }}</p>
          </header>

          <form class="grid gap-4 sm:grid-cols-2" @submit.prevent="submitEdit">
            <div>
              <label for="edit-fullname" class="block text-sm font-semibold text-ink mb-2">
                Full name
              </label>
              <input
                id="edit-fullname"
                v-model="editForm.fullName"
                type="text"
                class="form-input"
                required
                maxlength="200"
              />
            </div>
            <div>
              <label for="edit-role" class="block text-sm font-semibold text-ink mb-2">
                Role
              </label>
              <select id="edit-role" v-model="editForm.role" class="form-input" required>
                <option v-for="role in ROLE_OPTIONS" :key="role" :value="role">
                  {{ formatRole(role) }}
                </option>
              </select>
            </div>
            <div class="sm:col-span-2 flex flex-wrap items-center gap-3">
              <button type="submit" class="btn-primary" :disabled="saving">
                {{ saving ? 'Saving…' : 'Save changes' }}
              </button>
              <button type="button" class="btn-secondary" @click="editingUser = null">
                Cancel
              </button>
              <p v-if="editError" class="text-sm text-clinical-danger" role="alert">
                {{ editError }}
              </p>
            </div>
          </form>
        </section>
      </div>
    </div>

    <ConfirmDialog
      :open="!!resetTarget"
      title="Reset password"
      body="Set a new temporary password for this user. They can change it after signing in."
      confirm-label="Reset password"
      variant="danger"
      :confirm-disabled="!resetPasswordValue.trim() || resetting"
      @confirm="confirmReset"
      @cancel="closeReset"
    >
      <p v-if="resetTarget" class="text-sm text-ink-secondary mb-3">
        User: <span class="font-medium text-ink-strong">{{ resetTarget.fullName }}</span>
        ({{ resetTarget.username }})
      </p>
      <label for="reset-password" class="block text-sm font-semibold text-ink mb-2">
        New password
      </label>
      <input
        id="reset-password"
        v-model="resetPasswordValue"
        type="password"
        class="form-input"
        autocomplete="new-password"
        placeholder="Min. 8 chars, 1 uppercase, 1 digit"
        data-testid="users-reset-password-input"
      />
      <p v-if="resetError" class="mt-2 text-sm text-clinical-danger" role="alert">
        {{ resetError }}
      </p>
    </ConfirmDialog>
  </div>
</template>

<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue'
import { useUsersStore } from '../stores/users'
import { useToast } from '../composables/useToast'
import AppHeader from '../components/AppHeader.vue'
import ConfirmDialog from '../components/ConfirmDialog.vue'
import EmptyState from '../components/EmptyState.vue'
import InlineError from '../components/InlineError.vue'
import SkeletonBlock from '../components/SkeletonBlock.vue'
import type { UserRoleString, UserSummary } from '../types'

const ROLE_OPTIONS: UserRoleString[] = [
  'INTAKE_CLERK',
  'DATA_ENTRY_CLERK',
  'VERIFIER',
  'CLINICAL_APPROVER',
  'CLINICIAN',
  'ADMINISTRATOR',
]

const usersStore = useUsersStore()
const toast = useToast()

const roleFilter = ref('')
const showCreate = ref(false)
const creating = ref(false)
const createError = ref('')
const createForm = reactive({
  username: '',
  fullName: '',
  role: 'DATA_ENTRY_CLERK' as string,
  password: '',
})

const editingUser = ref<UserSummary | null>(null)
const saving = ref(false)
const editError = ref('')
const editForm = reactive({
  fullName: '',
  role: '',
})

const resetTarget = ref<UserSummary | null>(null)
const resetPasswordValue = ref('')
const resetError = ref('')
const resetting = ref(false)

function formatRole(role: string): string {
  return role.replace(/_/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase())
}

async function loadUsers() {
  await usersStore.listUsers(roleFilter.value || undefined)
}

function resetCreateForm() {
  createForm.username = ''
  createForm.fullName = ''
  createForm.role = 'DATA_ENTRY_CLERK'
  createForm.password = ''
  createError.value = ''
}

async function submitCreate() {
  creating.value = true
  createError.value = ''
  try {
    await usersStore.createUser({
      username: createForm.username.trim(),
      fullName: createForm.fullName.trim(),
      role: createForm.role,
      password: createForm.password,
    })
    toast.success('User created')
    showCreate.value = false
    resetCreateForm()
    await loadUsers()
  } catch (e: unknown) {
    createError.value = e instanceof Error ? e.message : 'Failed to create user'
  } finally {
    creating.value = false
  }
}

function startEdit(user: UserSummary) {
  editingUser.value = user
  editForm.fullName = user.fullName
  editForm.role = user.role
  editError.value = ''
}

async function submitEdit() {
  if (!editingUser.value) return
  saving.value = true
  editError.value = ''
  try {
    await usersStore.updateUser(editingUser.value.id, {
      fullName: editForm.fullName.trim(),
      role: editForm.role,
    })
    toast.success('User updated')
    editingUser.value = null
    await loadUsers()
  } catch (e: unknown) {
    editError.value = e instanceof Error ? e.message : 'Failed to update user'
  } finally {
    saving.value = false
  }
}

async function deactivateUser(user: UserSummary) {
  try {
    await usersStore.updateUser(user.id, { isActive: false })
    toast.warning(`${user.fullName} deactivated`)
    if (editingUser.value?.id === user.id) editingUser.value = null
    await loadUsers()
  } catch (e: unknown) {
    toast.error(e instanceof Error ? e.message : 'Failed to deactivate user')
  }
}

function openReset(user: UserSummary) {
  resetTarget.value = user
  resetPasswordValue.value = ''
  resetError.value = ''
}

function closeReset() {
  resetTarget.value = null
  resetPasswordValue.value = ''
  resetError.value = ''
}

async function confirmReset() {
  if (!resetTarget.value) return
  resetting.value = true
  resetError.value = ''
  try {
    await usersStore.resetPassword(resetTarget.value.id, resetPasswordValue.value)
    toast.success(`Password reset for ${resetTarget.value.username}`)
    closeReset()
  } catch (e: unknown) {
    resetError.value = e instanceof Error ? e.message : 'Failed to reset password'
  } finally {
    resetting.value = false
  }
}

onMounted(loadUsers)
</script>
