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

  let { session } = $props()

  let search = $state('')
  let filterDept = $state('')
  let filterStatus = $state('')
  let error = $state('')
  let showAdd = $state(false)
  let adding = $state(false)
  let newName = $state('')
  let newEmail = $state('')
  let newDeptID = $state('')
  let newIsLead = $state(false)
  let newNote = $state('')

  let editID = $state(null)
  let editDeptID = $state('')
  let editIsLead = $state(false)
  let editNote = $state('')
  let saving = $state(false)

  const role = $derived(session?.user?.role ?? '')
  const canManage = $derived(['admin', 'ticketing', 'staffing', 'colead'].includes(role))
  const canConfirm = $derived(['admin', 'staffing', 'colead'].includes(role))
  const myDeptIDs = $derived(session?.user?.department_ids ?? [])

  // Auto-filter coleads to their department on mount
  $effect(() => {
    if (role === 'colead' && myDeptIDs.length > 0 && !filterDept) {
      filterDept = String(myDeptIDs[0])
    }
  })

  const allVolunteers = liveQuery(() =>
    db.volunteers.filter(v => !v.deleted_at).toArray()
  )
  const allParticipants = liveQuery(() => db.participants.toArray())
  const allTickets = liveQuery(() => db.tickets.filter(t => !t.deleted_at).toArray())
  const allDepts = liveQuery(() =>
    db.departments.filter(d => !d.deleted_at).toArray()
      .then(arr => arr.sort((a, b) => a.name.localeCompare(b.name)))
  )

  const filtered = $derived.by(() => {
    const list = $allVolunteers ?? []
    const s = search.toLowerCase()
    return list
      .filter(v => {
        if (filterDept && v.department_id !== parseInt(filterDept)) return false
        if (filterStatus === 'unconfirmed' && v.email_confirmed) return false
        if (filterStatus === 'registered' && (!v.email_confirmed || v.confirmed)) return false
        if (filterStatus === 'confirmed' && (!v.confirmed || v.checked_in)) return false
        if (filterStatus === 'ready' && !v.checked_in) return false
        if (s && !v.name.toLowerCase().includes(s) &&
            !(v.email || '').toLowerCase().includes(s)) return false
        return true
      })
      .sort((a, b) => a.name.localeCompare(b.name))
  })

  async function checkIn(v) {
    try {
      const updated = await api.volunteers.checkIn(v.id)
      await db.volunteers.put(updated)
    } catch (err) {
      error = err.message
    }
  }

  async function confirmVolunteer(v) {
    try {
      const updated = await api.volunteers.confirm(v.id)
      await db.volunteers.put(updated)
    } catch (err) {
      error = err.message
    }
  }

  async function addVolunteer(e) {
    e.preventDefault()
    adding = true
    error = ''
    try {
      const data = {
        name: newName,
        email: newEmail,
        is_lead: newIsLead,
        note: newNote,
      }
      if (newDeptID) data.department_id = parseInt(newDeptID)
      const v = await api.volunteers.create(data)
      await db.volunteers.put(v)
      showAdd = false
      newName = newEmail = newNote = ''
      newDeptID = ''
      newIsLead = false
    } catch (err) {
      error = err.message
    } finally {
      adding = false
    }
  }

  async function deleteVolunteer(v) {
    if (!confirm(`Delete volunteer "${v.name}"?`)) return
    try {
      await api.volunteers.delete(v.id)
      await db.volunteers.delete(v.id)
    } catch (err) {
      error = err.message
    }
  }

  function startEdit(v) {
    editID = v.id
    editDeptID = v.department_id ? String(v.department_id) : ''
    editIsLead = v.is_lead
    editNote = v.note ?? ''
  }

  function cancelEdit() {
    editID = null
  }

  async function saveVolunteer(v) {
    saving = true
    error = ''
    try {
      const updated = await api.volunteers.update(v.id, {
        ...v,
        department_id: editDeptID ? parseInt(editDeptID) : null,
        is_lead: editIsLead,
        note: editNote,
      })
      await db.volunteers.put(updated)
      editID = null
    } catch (err) {
      error = err.message
    } finally {
      saving = false
    }
  }

  function deptFor(id) {
    return ($allDepts ?? []).find(d => d.id === id)
  }

  function participantHasTickets(participantId) {
    if (!participantId) return false
    return ($allTickets ?? []).some(t => t.participant_id === participantId)
  }

  function participantFor(id) {
    return ($allParticipants ?? []).find(p => p.id === id) ?? null
  }
</script>

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

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

  {#if showAdd && canManage}
    <div class="card" style="margin-bottom:1.5rem">
      <form onsubmit={addVolunteer}>
        <div class="form-grid" style="display:grid;grid-template-columns:1fr 1fr;gap:1rem">
          <div class="form-group">
            <label for="v-name">Name *</label>
            <input id="v-name" bind:value={newName} required placeholder="Full name" />
          </div>
          <div class="form-group">
            <label for="v-email">Email</label>
            <input id="v-email" type="email" bind:value={newEmail} placeholder="email@example.com" />
          </div>
          <div class="form-group">
            <label for="v-dept">Department</label>
            <select id="v-dept" bind:value={newDeptID}>
              <option value="">No department</option>
              {#each $allDepts ?? [] as d}
                <option value={String(d.id)}>{d.name}</option>
              {/each}
            </select>
          </div>
        </div>
        <div class="form-group">
          <label for="v-note">Note</label>
          <input id="v-note" bind:value={newNote} placeholder="Optional note" />
        </div>
        <div style="margin-bottom:1rem">
          <label style="display:flex;align-items:center;gap:0.5rem;cursor:pointer">
            <input type="checkbox" style="width:auto" bind:checked={newIsLead} />
            Department lead
          </label>
        </div>
        <div class="actions">
          <button type="submit" class="btn btn-primary" disabled={adding}>
            {adding ? 'Adding…' : 'Add volunteer'}
          </button>
          <button type="button" class="btn btn-ghost" onclick={() => showAdd = false}>Cancel</button>
        </div>
      </form>
    </div>
  {/if}

  <div class="search-bar">
    <input placeholder="Search name, email…" bind:value={search} />
    {#if ($allDepts ?? []).length > 0}
      <select bind:value={filterDept} style="width:auto">
        <option value="">All departments</option>
        {#each $allDepts ?? [] as d}
          <option value={String(d.id)}>{d.name}</option>
        {/each}
      </select>
    {/if}
    <select bind:value={filterStatus} style="width:auto">
      <option value="">All statuses</option>
      <option value="unconfirmed">Unconfirmed</option>
      <option value="registered">Registered</option>
      <option value="confirmed">Confirmed</option>
      <option value="ready">Ready</option>
    </select>
    <span class="text-muted" style="font-size:0.85rem;white-space:nowrap">
      {filtered.length} shown
    </span>
  </div>

  {#if ($allVolunteers ?? []).length === 0}
    <div class="empty">
      <strong>No volunteers yet</strong>
      <p>Add volunteers manually above, or enable public signup in Settings.</p>
    </div>
  {:else}
    <div class="table-wrap">
      <table>
        <thead>
          <tr>
            <th>Name</th>
            <th>Department</th>
            <th>Status</th>
            <th></th>
            {#if canManage}<th></th>{/if}
          </tr>
        </thead>
        <tbody>
          {#each filtered as v (v.id)}
            {@const dept = deptFor(v.department_id)}
            {#if editID === v.id}
              <tr class="edit-row">
                <td class="td-name" style="width:100%">
                  <strong>{v.name}</strong>
                  {#if v.email}<div class="text-muted" style="font-size:0.78rem">{v.email}</div>{/if}
                </td>
                <td class="td-edit-dept">
                  <select bind:value={editDeptID} style="margin:0">
                    <option value="">No department</option>
                    {#each $allDepts ?? [] as d}
                      <option value={String(d.id)}>{d.name}</option>
                    {/each}
                  </select>
                </td>
                <td class="td-edit-checks">
                  <label style="display:flex;align-items:center;gap:0.4rem;cursor:pointer;white-space:nowrap">
                    <input type="checkbox" style="width:auto" bind:checked={editIsLead} /> Co-Lead
                  </label>
                </td>
                <td class="td-edit-note">
                  <input bind:value={editNote} placeholder="Note" style="margin:0" />
                </td>
                <td class="td-actions">
                  <button class="btn btn-primary btn-sm" onclick={() => saveVolunteer(v)} disabled={saving}>
                    {saving ? '…' : 'Save'}
                  </button>
                  <button class="btn btn-ghost btn-sm" onclick={cancelEdit}>Cancel</button>
                </td>
              </tr>
            {:else}
              <tr>
                <td class="td-name">
                  <strong>{v.name}</strong>
                  {#if v.is_lead}
                    <span class="badge badge-lead" style="margin-left:0.4rem">Co-Lead</span>
                  {/if}
                  {#if !v.participant_id}
                    <span class="badge badge-unchecked" style="margin-left:0.4rem" title="Not linked to a participant">No ticket</span>
                  {:else if !participantHasTickets(v.participant_id)}
                    <span class="badge badge-partial" style="margin-left:0.4rem" title="No ticket on file">No ticket</span>
                  {/if}
                  {#if v.email}
                    <div class="text-muted" style="font-size:0.78rem">{v.email}</div>
                  {/if}
                  {#if v.note}
                    <div class="text-muted" style="font-size:0.78rem">{v.note}</div>
                  {/if}
                </td>
                <td class="td-dept text-muted">
                  {#if dept}
                    <span class="dept-dot" style="background:{dept.color};margin-right:0.4rem"></span>{dept.name}
                  {:else}
                    —
                  {/if}
                </td>
                <td class="td-status">
                  {#if v.checked_in}
                    <span class="badge badge-checked">Ready</span>
                  {:else if v.confirmed}
                    <span class="badge badge-confirmed">Confirmed</span>
                  {:else if v.email_confirmed}
                    <span class="badge badge-registered">Registered</span>
                  {:else}
                    <span class="badge badge-unchecked">Unconfirmed</span>
                  {/if}
                  {#if v.checked_in_at}
                    <div class="text-muted" style="font-size:0.75rem">
                      {new Date(v.checked_in_at).toLocaleTimeString()}
                    </div>
                  {/if}
                </td>
                <td class="td-ready">
                  {#if !v.checked_in}
                    <CheckInButton onclick={() => checkIn(v)} />
                  {/if}
                </td>
                {#if canManage}
                  <td class="td-actions">
                    {#if canConfirm && v.email_confirmed && !v.confirmed}
                      <button class="btn btn-primary btn-sm" onclick={() => confirmVolunteer(v)}>Confirm</button>
                    {/if}
                    <button class="btn btn-ghost btn-sm" onclick={() => startEdit(v)}>Edit</button>
                    <button class="btn btn-danger btn-sm" onclick={() => deleteVolunteer(v)}>Delete</button>
                  </td>
                {/if}
              </tr>
            {/if}
          {/each}
        </tbody>
      </table>
    </div>
  {/if}
</div>

<style>
  @media (max-width: 640px) {
    .td-name { flex: 1; min-width: 0; order: 1; }
    .td-ready { flex-shrink: 0; align-self: flex-start; order: 2; }
    .td-dept { width: 100%; order: 3; }
    .td-status { width: 100%; order: 4; }
    .td-actions { width: 100%; order: 5; display: flex; justify-content: flex-end; }
    .edit-row td { width: 100%; }
    .td-edit-dept, .td-edit-checks, .td-edit-note { width: 100%; }
  }
</style>
