<script>
  import { liveQuery } from 'dexie'
  import { db } from '../db.js'
  import { api } from '../api.js'

  let { session } = $props()

  let users = $state([])
  let loadError = $state('')
  let error = $state('')
  let loading = $state(true)

  let showAdd = $state(false)
  let adding = $state(false)
  let newUsername = $state('')
  let newPassword = $state('')
  let newRole = $state('gate')
  let newDeptIDs = $state([])

  let editID = $state(null)
  let editRole = $state('')
  let editDeptIDs = $state([])
  let editPassword = $state('')
  let saving = $state(false)

  const allDepts = liveQuery(() =>
    db.departments.filter(d => !d.deleted_at).toArray()
      .then(arr => arr.sort((a, b) => a.name.localeCompare(b.name)))
  )

  const roles = ['admin', 'ticketing', 'staffing', 'colead', 'gatekeeper']

  const me = $derived(session?.user?.id)

  async function loadUsers() {
    loading = true
    try {
      users = await api.users.list()
    } catch (err) {
      loadError = err.message
    } finally {
      loading = false
    }
  }

  $effect(() => { loadUsers() })

  async function addUser(e) {
    e.preventDefault()
    adding = true
    error = ''
    try {
      const u = await api.users.create({
        username: newUsername,
        password: newPassword,
        role: newRole,
        department_ids: newDeptIDs,
      })
      users = [...users, u]
      showAdd = false
      newUsername = newPassword = ''
      newRole = 'gate'
      newDeptIDs = []
    } catch (err) {
      error = err.message
    } finally {
      adding = false
    }
  }

  function startEdit(u) {
    editID = u.id
    editRole = u.role
    editDeptIDs = [...(u.department_ids || [])]
    editPassword = ''
  }

  function cancelEdit() {
    editID = null
  }

  async function saveUser(u) {
    saving = true
    error = ''
    try {
      const payload = { role: editRole, department_ids: editDeptIDs }
      if (editPassword) payload.password = editPassword
      const updated = await api.users.update(u.id, payload)
      users = users.map(x => x.id === u.id ? updated : x)
      editID = null
    } catch (err) {
      error = err.message
    } finally {
      saving = false
    }
  }

  async function deleteUser(u) {
    if (!confirm(`Delete user "${u.username}"? This cannot be undone.`)) return
    try {
      await api.users.delete(u.id)
      users = users.filter(x => x.id !== u.id)
    } catch (err) {
      error = err.message
    }
  }

  function toggleDept(id, list) {
    const idx = list.indexOf(id)
    if (idx === -1) return [...list, id]
    return list.filter(x => x !== id)
  }

  function deptNamesFor(ids) {
    const depts = $allDepts ?? []
    return ids.map(id => depts.find(d => d.id === id)?.name).filter(Boolean).join(', ') || '—'
  }

  function roleLabel(r) {
    return { admin: 'Admin', coordinator: 'Coordinator', ticketing: 'Ticketing', gate: 'Gate', volunteer_lead: 'Vol. Lead' }[r] || r
  }
</script>

<div class="page">
  <div class="page-header">
    <h1 class="page-title">Users</h1>
    <div class="actions">
      <button class="btn btn-primary btn-sm" onclick={() => showAdd = !showAdd}>+ Add user</button>
    </div>
  </div>

  {#if loadError}
    <div class="alert alert-error">{loadError}</div>
  {/if}
  {#if error}
    <div class="alert alert-error">{error}</div>
  {/if}

  {#if showAdd}
    <div class="card" style="margin-bottom:1.5rem">
      <form onsubmit={addUser}>
        <div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:1rem">
          <div class="form-group">
            <label for="u-username">Username *</label>
            <input id="u-username" bind:value={newUsername} required placeholder="username" autocomplete="off" />
          </div>
          <div class="form-group">
            <label for="u-password">Password *</label>
            <input id="u-password" type="password" bind:value={newPassword} required autocomplete="new-password" />
          </div>
          <div class="form-group">
            <label for="u-role">Role *</label>
            <select id="u-role" bind:value={newRole}>
              {#each roles as r}
                <option value={r}>{roleLabel(r)}</option>
              {/each}
            </select>
          </div>
        </div>
        {#if ($allDepts ?? []).length > 0}
          <div class="form-group">
            <span style="font-size:0.82rem;color:var(--c-muted);font-weight:500">Departments</span>
            <div style="display:flex;flex-wrap:wrap;gap:0.5rem;margin-top:0.35rem">
              {#each $allDepts ?? [] as d}
                <label style="display:flex;align-items:center;gap:0.35rem;cursor:pointer;font-size:0.875rem;color:var(--c-text)">
                  <input type="checkbox" style="width:auto"
                    checked={newDeptIDs.includes(d.id)}
                    onchange={() => newDeptIDs = toggleDept(d.id, newDeptIDs)} />
                  <span class="dept-dot" style="background:{d.color}"></span>
                  {d.name}
                </label>
              {/each}
            </div>
          </div>
        {/if}
        <div class="actions">
          <button type="submit" class="btn btn-primary" disabled={adding}>
            {adding ? 'Adding…' : 'Add user'}
          </button>
          <button type="button" class="btn btn-ghost" onclick={() => showAdd = false}>Cancel</button>
        </div>
      </form>
    </div>
  {/if}

  {#if loading}
    <div class="text-muted" style="padding:2rem 0">Loading…</div>
  {:else if users.length === 0}
    <div class="empty">
      <strong>No users yet</strong>
    </div>
  {:else}
    <div class="table-wrap">
      <table>
        <thead>
          <tr>
            <th>Username</th>
            <th>Role</th>
            <th>Departments</th>
            <th></th>
          </tr>
        </thead>
        <tbody>
          {#each users as u (u.id)}
            {#if editID === u.id}
              <tr>
                <td><strong>{u.username}</strong> {#if u.id === me}<span class="badge badge-role">you</span>{/if}</td>
                <td>
                  <select bind:value={editRole} style="width:auto;margin:0">
                    {#each roles as r}
                      <option value={r}>{roleLabel(r)}</option>
                    {/each}
                  </select>
                </td>
                <td>
                  {#if ($allDepts ?? []).length > 0}
                    <div style="display:flex;flex-wrap:wrap;gap:0.4rem">
                      {#each $allDepts ?? [] as d}
                        <label style="display:flex;align-items:center;gap:0.3rem;cursor:pointer;font-size:0.82rem;color:var(--c-text)">
                          <input type="checkbox" style="width:auto"
                            checked={editDeptIDs.includes(d.id)}
                            onchange={() => editDeptIDs = toggleDept(d.id, editDeptIDs)} />
                          {d.name}
                        </label>
                      {/each}
                    </div>
                  {/if}
                  <input type="password" bind:value={editPassword}
                    placeholder="New password (leave blank to keep)"
                    style="margin-top:0.5rem" autocomplete="new-password" />
                </td>
                <td>
                  <div class="actions">
                    <button class="btn btn-primary btn-sm" onclick={() => saveUser(u)} disabled={saving}>
                      {saving ? '…' : 'Save'}
                    </button>
                    <button class="btn btn-ghost btn-sm" onclick={cancelEdit}>Cancel</button>
                  </div>
                </td>
              </tr>
            {:else}
              <tr>
                <td>
                  <strong>{u.username}</strong>
                  {#if u.id === me}
                    <span class="badge badge-role" style="margin-left:0.4rem">you</span>
                  {/if}
                </td>
                <td><span class="badge badge-role">{roleLabel(u.role)}</span></td>
                <td class="text-muted">{deptNamesFor(u.department_ids || [])}</td>
                <td>
                  <div class="actions">
                    <button class="btn btn-ghost btn-sm" onclick={() => startEdit(u)}>Edit</button>
                    {#if u.id !== me}
                      <button class="btn btn-danger btn-sm" onclick={() => deleteUser(u)}>Delete</button>
                    {/if}
                  </div>
                </td>
              </tr>
            {/if}
          {/each}
        </tbody>
      </table>
    </div>
  {/if}
</div>
