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

  let { session } = $props()

  let search = $state('')
  let error = $state('')
  let success = $state('')
  let generating = $state(false)
  let emailing = $state(false)
  let mergeMode = $state(false)
  let mergeSource = $state(null)   // participant being merged away
  let mergeTarget = $state(null)   // participant to keep
  let expandedId = $state(null)
  let expandedTickets = $state([])

  const role = $derived(session?.user?.role ?? '')
  const canManage = $derived(['admin', 'ticketing'].includes(role))

  const allParticipants = liveQuery(() => db.participants.toArray())
  const allTickets = liveQuery(() => db.tickets.toArray())

  const filtered = $derived.by(() => {
    const list = $allParticipants ?? []
    const s = search.toLowerCase().trim()
    return list
      .filter(p => {
        if (!s) return true
        return p.preferred_name?.toLowerCase().includes(s) ||
               p.email?.toLowerCase().includes(s)
      })
      .sort((a, b) => (a.preferred_name || a.email).localeCompare(b.preferred_name || b.email))
  })

  function ticketsFor(participantId) {
    return ($allTickets ?? []).filter(t => t.participant_id === participantId)
  }

  function checkedInCount(participantId) {
    return ticketsFor(participantId).filter(t => t.checked_in_at).length
  }

  async function toggleExpand(id) {
    if (expandedId === id) {
      expandedId = null
      expandedTickets = []
      return
    }
    expandedId = id
    expandedTickets = ticketsFor(id)
  }

  async function generateCodes() {
    generating = true
    error = ''
    success = ''
    try {
      const result = await api.tickets.generateCodes()
      success = `Generated ${result.generated} code${result.generated !== 1 ? 's' : ''}.`
    } catch (err) {
      error = err.message
    } finally {
      generating = false
    }
  }

  async function emailAll() {
    if (!confirm('Send code emails to all participants with a ticket code and email?')) return
    emailing = true
    error = ''
    success = ''
    try {
      const result = await api.tickets.emailAllCodes()
      success = `Sent ${result.sent} email${result.sent !== 1 ? 's' : ''}${result.skipped ? `, skipped ${result.skipped}` : ''}.`
      if (result.errors?.length) error = result.errors.join('; ')
    } catch (err) {
      error = err.message
    } finally {
      emailing = false
    }
  }

  function startMerge(p) {
    mergeMode = true
    mergeSource = p
    mergeTarget = null
    error = ''
  }

  function cancelMerge() {
    mergeMode = false
    mergeSource = null
    mergeTarget = null
  }

  async function confirmMerge() {
    if (!mergeSource || !mergeTarget) return
    error = ''
    try {
      const result = await api.participants.merge(mergeTarget.id, mergeSource.id)
      success = `Merged "${mergeSource.preferred_name || mergeSource.email}" into "${mergeTarget.preferred_name || mergeTarget.email}".`
      if (result.participant) await db.participants.put(result.participant)
      if (result.tickets?.length) await db.tickets.bulkPut(result.tickets)
      await db.participants.delete(mergeSource.id)
      cancelMerge()
    } catch (err) {
      error = err.message
    }
  }

  function fmtTime(ts) {
    if (!ts) return ''
    return new Date(ts).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
  }
</script>

<div class="page">
  <div class="page-header">
    <h1 class="page-title">Participants</h1>
    <div class="actions">
      {#if canManage}
        <a href="/api/participants/export" class="btn btn-ghost btn-sm">Export CSV</a>
        <button class="btn btn-ghost btn-sm" onclick={generateCodes} disabled={generating}>
          {generating ? '…' : '⚿ Generate Codes'}
        </button>
        <a href="/api/tickets/export-links" class="btn btn-ghost btn-sm">Export Links</a>
        <button class="btn btn-ghost btn-sm" onclick={emailAll} disabled={emailing}>
          {emailing ? '…' : '✉ Email All'}
        </button>
      {/if}
    </div>
  </div>

  {#if mergeMode && mergeSource}
    <div class="card" style="margin-bottom:1.5rem;border-color:var(--c-accent)">
      <div style="margin-bottom:0.75rem">
        <strong>Merge:</strong> "{mergeSource.preferred_name || mergeSource.email}" will be merged into the participant you select below.
        All their tickets and volunteer records will move to the target.
      </div>
      {#if mergeTarget}
        <div style="margin-bottom:0.75rem">
          <strong>Target:</strong> {mergeTarget.preferred_name || mergeTarget.email} ({mergeTarget.email})
        </div>
        <div class="actions">
          <button class="btn btn-primary" onclick={confirmMerge}>Confirm merge</button>
          <button class="btn btn-ghost" onclick={cancelMerge}>Cancel</button>
        </div>
      {:else}
        <div class="text-muted" style="font-size:0.875rem">Click a participant row below to select as merge target.</div>
        <div class="actions" style="margin-top:0.5rem">
          <button class="btn btn-ghost" onclick={cancelMerge}>Cancel</button>
        </div>
      {/if}
    </div>
  {/if}

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

  <div class="search-bar">
    <input placeholder="Search name or email…" bind:value={search} />
    <span class="text-muted" style="font-size:0.85rem;white-space:nowrap">
      {filtered.length} shown
    </span>
  </div>

  {#if ($allParticipants ?? []).length === 0}
    <div class="empty">
      <strong>No participants yet</strong>
      <p>Import a CSV or wait for volunteer signups.</p>
    </div>
  {:else}
    <div class="table-wrap">
      <table>
        <thead>
          <tr>
            <th>Name</th>
            <th>Email</th>
            <th>Tickets</th>
            <th>Status</th>
            {#if canManage}<th></th>{/if}
          </tr>
        </thead>
        <tbody>
          {#each filtered as p (p.id)}
            {@const pts = ticketsFor(p.id)}
            {@const ci = checkedInCount(p.id)}
            {@const isExpanded = expandedId === p.id}
            {@const isMergeTarget = mergeMode && mergeSource?.id !== p.id}
            <tr
              class:merge-target={isMergeTarget}
              onclick={mergeMode && mergeSource?.id !== p.id ? () => { mergeTarget = p } : null}
              style={mergeMode && mergeSource?.id !== p.id ? 'cursor:pointer' : ''}
            >
              <td>
                <strong>{p.preferred_name || '—'}</strong>
                {#if p.pronouns}
                  <span class="text-muted" style="font-size:0.78rem"> · {p.pronouns}</span>
                {/if}
                {#if p.note}
                  <div class="text-muted" style="font-size:0.78rem">{p.note}</div>
                {/if}
              </td>
              <td class="text-muted">{p.email || '—'}</td>
              <td>
                {#if pts.length > 0}
                  <button class="btn btn-ghost btn-sm" onclick={(e) => { e.stopPropagation(); toggleExpand(p.id) }}>
                    {pts.length} ticket{pts.length !== 1 ? 's' : ''}
                    {isExpanded ? '▲' : '▼'}
                  </button>
                {:else}
                  <span class="text-muted">—</span>
                {/if}
              </td>
              <td>
                {#if pts.length > 0}
                  <span class="badge {ci === pts.length ? 'badge-checked' : ci > 0 ? 'badge-partial' : 'badge-unchecked'}">
                    {ci}/{pts.length} in
                  </span>
                {:else}
                  <span class="badge badge-unchecked">No ticket</span>
                {/if}
              </td>
              {#if canManage}
                <td>
                  {#if !mergeMode}
                    <button class="btn btn-ghost btn-sm" onclick={(e) => { e.stopPropagation(); startMerge(p) }}
                      title="Merge this participant into another">⇄</button>
                  {/if}
                </td>
              {/if}
            </tr>
            {#if isExpanded && pts.length > 0}
              <tr class="ticket-rows">
                <td colspan="5">
                  <div class="ticket-list">
                    {#each pts as tk (tk.id)}
                      <div class="ticket-row">
                        <div>
                          <strong>{tk.name || '(unnamed)'}</strong>
                          {#if tk.ticket_type}
                            <span class="text-muted"> · {tk.ticket_type}</span>
                          {/if}
                          {#if tk.external_id}
                            <span class="text-muted" style="font-size:0.78rem"> · #{tk.external_id}</span>
                          {/if}
                          {#if tk.code}
                            <div style="font-size:0.75rem;margin-top:0.15rem">
                              <code style="color:var(--c-accent-h)">{tk.code}</code>
                              {#if p.email && canManage}
                                <button class="btn btn-ghost btn-sm" style="padding:0.1rem 0.4rem;margin-left:0.25rem"
                                  onclick={() => api.tickets.emailCode(tk.id).then(() => success = 'Email sent.').catch(e => error = e.message)}>✉</button>
                              {/if}
                            </div>
                          {/if}
                        </div>
                        <div style="text-align:right">
                          {#if tk.checked_in_at}
                            <span class="badge badge-checked">In {fmtTime(tk.checked_in_at)}</span>
                          {:else}
                            <span class="badge badge-unchecked">Pending</span>
                          {/if}
                          <div class="text-muted" style="font-size:0.75rem">{tk.source}</div>
                        </div>
                      </div>
                    {/each}
                  </div>
                </td>
              </tr>
            {/if}
          {/each}
        </tbody>
      </table>
    </div>
  {/if}
</div>

<style>
  .merge-target:hover { background: rgba(var(--c-accent-rgb, 99,102,241), 0.08); }
  .ticket-rows td { padding: 0; background: var(--c-bg); }
  .ticket-list { padding: 0.5rem 1rem 0.75rem; display: flex; flex-direction: column; gap: 0.4rem; }
  .ticket-row {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    padding: 0.4rem 0.6rem;
    border-radius: 6px;
    background: var(--c-surface);
    font-size: 0.875rem;
  }
  .badge-partial {
    background: rgba(245,158,11,0.15);
    color: var(--c-warn);
    padding: 0.15rem 0.5rem;
    border-radius: 99px;
    font-size: 0.75rem;
    font-weight: 600;
  }
</style>
