jQuery(function ($) {
  const listEl = $('#sbc-admin-customer-list');
  const threadEl = $('#sbc-admin-thread');
  const searchEl = $('#sbc-admin-search');
  const statusEl = $('#sbc-admin-filter-status');
  const refreshBtn = $('#sbc-admin-refresh');
  const deadzoneBtn = $('#sbc-admin-deadzone');
  const clearAllBtn = $('#sbc-admin-clear-all');

  let selectedChatId = 0;
  let selectedCustomerKey = '';
  let poller = null;
  let typingPingAt = 0;
  let searchDebounce = null;
  let currentResetVersion = parseInt(SBC_ADMIN.resetVersion, 10) || 1;
  let lastMessageCount = 0;
  let audioCtx = null;
  let refreshInFlight = false;
  let inboxRequest = null;
  let refreshGeneration = 0;
  let unreadBaselineReady = false;
  let lastTotalUnread = 0;

  function adminFormIsActive() {
    const active = document.activeElement;
    const formActive = !!(active && threadEl.length && threadEl[0].contains(active) &&
      $(active).is('textarea, input, select'));
    // Keep expanded provider/transaction details open. Polling may continue
    // updating the customer list, but must not rebuild the selected thread.
    return formActive || threadEl.find('details[open]').length > 0;
  }

  function esc(s) {
    return String(s || '').replace(/[&<>"']/g, function (m) {
      return ({
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#039;'
      })[m];
    });
  }

  function beep() {
    try {
      audioCtx = audioCtx || new (window.AudioContext || window.webkitAudioContext)();
      const osc = audioCtx.createOscillator();
      const gain = audioCtx.createGain();
      osc.type = 'sine';
      osc.frequency.value = 660;
      gain.gain.setValueAtTime(0.07, audioCtx.currentTime);
      gain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 0.3);
      osc.connect(gain);
      gain.connect(audioCtx.destination);
      osc.start();
      osc.stop(audioCtx.currentTime + 0.3);
    } catch (e) { /* ignore */ }
  }

  function statusBadge(status) {
    const s = status || 'waiting';
    return `<span class="sbc-badge sbc-status-${esc(s)}">${esc(s)}</span>`;
  }

  function isRecent(tsString, seconds = 4) {
    if (!tsString) return false;
    const ts = new Date(tsString.replace(' ', 'T')).getTime();
    return (Date.now() - ts) < (seconds * 1000);
  }

  function ajax(action, data) {
    return $.post(SBC_ADMIN.ajaxUrl, $.extend({
      action: action,
      nonce: SBC_ADMIN.nonce
    }, data || {}));
  }

  function renderCustomers(customers) {
    if (!customers || !customers.length) {
      listEl.html('<div class="sbc-admin-empty">No chats found.</div>');
      return;
    }

    const html = customers.map(function (c) {
      const active = (Number(c.latest_chat_id) === Number(selectedChatId)) || (c.customer_key === selectedCustomerKey);
      const balanceChip = c.user_id ? `<span class="sbc-balance-chip">${SBC_ADMIN.currency}${Number(c.balance).toFixed(2)}</span>` : '';
      const withdrawalChip = c.pending_withdrawal
        ? '<span class="sbc-withdrawal-chip" title="This customer has a pending withdrawal request">💸 Withdrawal pending</span>'
        : '';

      return `
        <button type="button"
                class="sbc-admin-customer-item ${active ? 'active' : ''}"
                data-chat-id="${esc(c.latest_chat_id)}"
                data-customer-key="${esc(c.customer_key)}">
          <div class="sbc-admin-row-top">
            <div>
              <div class="sbc-admin-name">${esc(c.full_name || c.customer_email || 'Unknown customer')}</div>
              <div class="sbc-admin-muted">${esc(c.customer_email || '')}</div>
              ${balanceChip}
              ${withdrawalChip}
            </div>
            <div>${statusBadge(c.latest_status)}</div>
          </div>

          <div class="sbc-admin-muted" style="margin-top:8px;">
            Service: ${esc(c.latest_service || '—')} • ${esc(c.chats_count)} chat(s)
          </div>

          <div class="sbc-admin-footer">
            <span>#${esc(c.latest_chat_id)} • ${esc(c.latest_updated_at || '')}</span>
            ${Number(c.unread_count) > 0 ? `<span class="sbc-unread">${esc(c.unread_count)} unread</span>` : ''}
          </div>
        </button>
      `;
    }).join('');

    listEl.html(html);
  }

  function cannedButtons() {
    const replies = SBC_ADMIN.cannedReplies || [];
    if (!replies.length) return '';

    return `<div id="sbc-admin-canned">${replies.map(function (r) {
      return `<button type="button" class="sbc-canned-btn" data-text="${esc(r)}">${esc(r.length > 40 ? r.slice(0, 40) + '…' : r)}</button>`;
    }).join('')}</div>`;
  }

  function renderThread(selected) {
    threadEl.removeClass('sbc-thread-loading');
    if (!selected) {
      threadEl.html('<div class="sbc-admin-empty">Select a customer to view the thread.</div>');
      return;
    }

    const isNewChat = Number(selected.chat_id) !== Number(selectedChatId);

    selectedChatId = Number(selected.chat_id);
    selectedCustomerKey = selected.customer_key || '';

    const typing = isRecent(selected.customer_typing_at, 4)
      ? '<div id="sbc-admin-thread-typing">Customer is typing...</div>'
      : '<div id="sbc-admin-thread-typing"></div>';

    const historyButtons = (selected.history || []).map(function (h) {
      const active = Number(h.chat_id) === Number(selectedChatId);
      return `<button type="button" class="sbc-history-btn ${active ? 'active' : ''}" data-chat-id="${esc(h.chat_id)}"><span><i></i>${esc('#' + h.chat_id)} • ${esc(h.status)}</span><small>${esc(h.updated_at || '')}</small></button>`;
    }).join('');

    const messages = (selected.messages || []).map(function (m) {
      const senderClass = m.sender_type === 'agent' ? 'agent' : m.sender_type === 'customer' ? 'user' : m.sender_type === 'warning' ? 'warning' : 'system';
      const label = m.sender_type === 'agent' ? 'Agent' : m.sender_type === 'customer' ? 'Customer' : m.sender_type === 'warning' ? '' : 'System';

      return `
        <div class="sbc-admin-msg ${senderClass}">
          ${label ? `<strong>${esc(label)} • ${esc(m.created_at)}</strong>` : ''}
          <div>${esc(m.message).replace(/\n/g, '<br>')}</div>
        </div>
      `;
    }).join('');

    if (isNewChat) {
      lastMessageCount = selected.messages ? selected.messages.length : 0;
    } else if (selected.messages && selected.messages.length > lastMessageCount) {
      const newest = selected.messages[selected.messages.length - 1];
      if (newest && newest.sender_type === 'customer') beep();
      lastMessageCount = selected.messages.length;
    }

    const isClosed = selected.status === 'closed';
    const customerName = selected.full_name || selected.customer_email || 'Unknown customer';
    const customerInitial = String(customerName).trim().charAt(0).toUpperCase() || '?';

    const ratingHtml = selected.rating
      ? `<div class="sbc-admin-rating">Rated ${'★'.repeat(selected.rating)}${'☆'.repeat(5 - selected.rating)}${selected.rating_feedback ? ' — "' + esc(selected.rating_feedback) + '"' : ''}</div>`
      : '';

    const balanceBox = selected.user_id ? `
      <div id="sbc-admin-balance-box">
        <div>Wallet balance: <span class="sbc-balance-amount">${SBC_ADMIN.currency}${Number(selected.balance || 0).toFixed(2)}</span></div>
        <div id="sbc-admin-adjust-row">
          <input type="number" id="sbc-adjust-amount" placeholder="Amount, e.g. 100 or -100" style="width:170px;">
          <input type="text" id="sbc-adjust-note" placeholder="Note (optional)" style="width:170px;">
          <button type="button" class="button" id="sbc-adjust-apply">Adjust balance</button>
        </div>
      </div>
    ` : '';

    const withdrawalAlert = selected.pending_withdrawal
      ? `<div class="sbc-admin-withdrawal-alert"><strong>! &nbsp; Pending withdrawal request</strong><span>This customer is waiting for a withdrawal review.</span><a class="button" href="${esc(SBC_ADMIN.withdrawalsUrl || '#')}">Review Withdrawal</a></div>`
      : '';

    const tx = selected.transaction_snapshot || null;
    const txSummary = tx && tx.summary ? tx.summary : null;
    const transactionCard = txSummary ? `
      <section class="sbc-side-card sbc-transaction-card">
        <h3>Attached VTUpress Transaction</h3>
        <dl>
          <div><dt>Service</dt><dd>${esc(txSummary.service)}</dd></div>
          <div><dt>Plan / Network</dt><dd>${esc(txSummary.plan || txSummary.network || '—')}</dd></div>
          <div><dt>Amount</dt><dd>${SBC_ADMIN.currency}${Number(txSummary.amount || 0).toFixed(2)}</dd></div>
          <div><dt>Recipient</dt><dd>${esc(txSummary.recipient || '—')}</dd></div>
          <div><dt>Status</dt><dd>${esc(txSummary.status || '—')}</dd></div>
          <div><dt>Reference</dt><dd>${esc(txSummary.reference || '—')}</dd></div>
          <div><dt>Balance</dt><dd>${esc(tx.balance_before || '—')} → ${esc(tx.balance_now || '—')}</dd></div>
        </dl>
        <details><summary>Provider response</summary><pre>${esc(tx.response_message || 'No provider response saved.')}</pre></details>
        <details><summary>Transaction details</summary><pre>${esc(JSON.stringify(tx.details || {}, null, 2))}</pre></details>
        <button type="button" class="button sbc-refresh-transaction">↻ Refresh Transaction</button>
      </section>` : '';

    $('#sbc-admin-thread').html(`
      <div class="sbc-thread-layout">
        <main class="sbc-chat-workspace">
          <div id="sbc-admin-thread-header">
            <div class="sbc-customer-identity"><span class="sbc-avatar">${esc(customerInitial)}</span><div><h2>${esc(customerName)}</h2><div class="sbc-admin-muted">${esc(selected.customer_email || '')}</div></div></div>
            <div class="sbc-thread-head-meta">${statusBadge(selected.status)}<span>${esc(selected.service_type || 'No service')}</span><span>Chat ID: #${esc(selected.chat_id)}</span></div>
          </div>
          <div id="sbc-admin-thread-meta">
            <div><small>Initial issue</small><strong>${esc(selected.initial_message || 'No initial issue provided')}</strong></div>
            <div><small>Service</small><strong>${esc(selected.service_type || 'Not set')}</strong></div>
            <div><small>Unread</small><strong>${esc(selected.admin_unread_count || 0)} message(s)</strong></div>
            <div><small>Bonus</small><strong>${Number(selected.compensation_awarded) === 1 ? 'Awarded' : 'Pending'} ${Number(selected.compensation_amount) > 0 ? `(₦${esc(selected.compensation_amount)})` : ''}</strong></div>
            <div><small>Updated</small><strong>${esc(selected.updated_at || '')}</strong></div>${ratingHtml}
          </div>
          ${typing}
          <div id="sbc-admin-messages">${messages || '<div class="sbc-admin-empty">No messages yet.</div>'}</div>
          <div class="sbc-admin-actions">
            <div class="sbc-reply-tabs"><strong>Reply</strong><span>Internal Note</span></div>
            ${cannedButtons()}
            <textarea id="sbc-admin-reply" placeholder="Type your reply here..."></textarea>
            <div class="sbc-admin-action-buttons"><button type="button" class="button" id="sbc-admin-close" ${isClosed ? 'disabled' : ''}>Close Chat</button><button type="button" class="button button-primary" id="sbc-admin-send" ${isClosed ? 'disabled' : ''}>➤ Send Reply</button></div>
          </div>
        </main>
        <aside class="sbc-customer-sidebar">
          <section class="sbc-side-card"><h3>Customer Details</h3><div class="sbc-side-profile"><span class="sbc-avatar">${esc(customerInitial)}</span><div><strong>${esc(customerName)}</strong><small>${esc(selected.customer_email || '')}</small></div></div></section>
          <section class="sbc-side-card"><h3>Wallet Balance</h3>${balanceBox}</section>
          ${transactionCard}
          ${withdrawalAlert}
          <section class="sbc-side-card sbc-history-card"><h3>Customer Chat History</h3><div id="sbc-admin-history"><div class="sbc-history-list">${historyButtons || '<div class="sbc-admin-muted">No history.</div>'}</div></div></section>
        </aside>
      </div>`);

    const msgBox = $('#sbc-admin-messages');
    if (msgBox.length) {
      msgBox.scrollTop(msgBox[0].scrollHeight);
    }
  }

  function handleResetVersion(newVersion) {
    const nv = parseInt(newVersion, 10) || currentResetVersion;
    if (nv !== currentResetVersion) {
      currentResetVersion = nv;
    }
  }

  function refreshInbox(markRead = false) {
    // A customer/history click must never wait behind a background poll.
    // Cancel the stale poll and immediately load the selected conversation.
    if (refreshInFlight) {
      if (!markRead) return;
      if (inboxRequest && typeof inboxRequest.abort === 'function') inboxRequest.abort();
    }

    const generation = ++refreshGeneration;
    refreshInFlight = true;
    inboxRequest = ajax('sbc_admin_get_inbox', {
      search: searchEl.val() || '',
      status: statusEl.val() || 'all',
      selected_chat_id: selectedChatId || 0,
      selected_customer_key: selectedCustomerKey || '',
      mark_read: markRead ? 1 : 0
    }).done(function (res) {
      if (generation !== refreshGeneration) return;
      if (!res || !res.success) return;

      const data = res.data || {};

      const totalUnread = data.global_unread_count !== undefined
        ? Number(data.global_unread_count) || 0
        : (data.customers || []).reduce(function (sum, customer) {
            return sum + (Number(customer.unread_count) || 0);
          }, 0);
      if (unreadBaselineReady && totalUnread > lastTotalUnread) beep();
      lastTotalUnread = totalUnread;
      unreadBaselineReady = true;

      if (data.reset_version) handleResetVersion(data.reset_version);

      renderCustomers(data.customers || []);

      if (data.selected_chat_id) {
        selectedChatId = Number(data.selected_chat_id);
      }

      if (data.selected_customer_key) {
        selectedCustomerKey = data.selected_customer_key;
      }

      // Polling used to replace the entire thread every 2.5 seconds, which
      // destroyed focused inputs and erased unfinished replies/adjustments.
      if (markRead || !adminFormIsActive()) {
        renderThread(data.selected);
      }

      if ((!selectedChatId || !selectedCustomerKey) && data.customers && data.customers.length) {
        selectedChatId = Number(data.customers[0].latest_chat_id);
        selectedCustomerKey = data.customers[0].customer_key;
        refreshInbox(true);
      }
    }).always(function () {
      if (generation === refreshGeneration) {
        refreshInFlight = false;
        inboxRequest = null;
        threadEl.removeClass('sbc-thread-loading');
      }
    });
  }

  function pingTyping() {
    if (!selectedChatId) return;

    const now = Date.now();
    if (now - typingPingAt < 1500) return;
    typingPingAt = now;

    ajax('sbc_admin_typing', {
      chat_id: selectedChatId
    });
  }

  refreshBtn.on('click', function () {
    refreshInbox(false);
  });

  deadzoneBtn.on('click', function () {
    if (!confirm('Reset frontend cache for all active customers?')) return;

    ajax('sbc_admin_deadzone_reset', {}).done(function (res) {
      if (!res || !res.success) {
        alert((res && res.data && res.data.message) ? res.data.message : 'Could not reset.');
        return;
      }

      alert('Deadzone reset complete. Customers will clear stale frontend state on next poll.');
      refreshInbox(false);
    });
  });

  clearAllBtn.on('click', function () {
    if (!confirm('This will delete all chats, messages, balances logs, and withdrawal requests. Continue?')) return;

    ajax('sbc_admin_clear_all', {}).done(function (res) {
      if (!res || !res.success) {
        alert((res && res.data && res.data.message) ? res.data.message : 'Could not clear all.');
        return;
      }

      selectedChatId = 0;
      selectedCustomerKey = '';
      alert('All chats/messages cleared.');
      refreshInbox(false);
    });
  });

  searchEl.on('input', function () {
    clearTimeout(searchDebounce);
    searchDebounce = setTimeout(function () {
      refreshInbox(false);
    }, 300);
  });

  statusEl.on('change', function () {
    refreshInbox(false);
  });

  listEl.on('click', '.sbc-admin-customer-item', function () {
    selectedChatId = Number($(this).data('chat-id'));
    selectedCustomerKey = String($(this).data('customer-key') || '');
    threadEl.addClass('sbc-thread-loading');
    refreshInbox(true);
  });

  threadEl.on('click', '.sbc-history-btn', function () {
    selectedChatId = Number($(this).data('chat-id'));
    threadEl.addClass('sbc-thread-loading');
    refreshInbox(true);
  });

  threadEl.on('click', '.sbc-canned-btn', function () {
    const box = $('#sbc-admin-reply');
    const existing = box.val();
    box.val(existing ? existing + '\n' + $(this).data('text') : $(this).data('text'));
    box.focus();
  });

  threadEl.on('input', '#sbc-admin-reply', function () {
    if ($(this).val().trim().length) {
      pingTyping();
    }
  });

  threadEl.on('click', '#sbc-admin-send', function () {
    const msg = $('#sbc-admin-reply').val().trim();
    if (!msg || !selectedChatId) return;

    const btn = $(this);
    btn.prop('disabled', true).text('Sending...');

    ajax('sbc_admin_reply', {
      chat_id: selectedChatId,
      message: msg
    }).done(function (res) {
      btn.prop('disabled', false).text('Send Reply');

      if (!res || !res.success) {
        alert((res && res.data && res.data.message) ? res.data.message : 'Could not send reply.');
        return;
      }

      $('#sbc-admin-reply').val('').focus();
      refreshInbox(true);
    });
  });

  threadEl.on('click', '#sbc-admin-close', function () {
    if (!selectedChatId) return;

    ajax('sbc_admin_close_chat', {
      chat_id: selectedChatId
    }).done(function (res) {
      if (!res || !res.success) {
        alert((res && res.data && res.data.message) ? res.data.message : 'Could not close chat.');
        return;
      }

      refreshInbox(true);
    });
  });

  threadEl.on('click', '#sbc-adjust-apply', function () {
    const amount = parseFloat($('#sbc-adjust-amount').val());
    const note = $('#sbc-adjust-note').val();

    if (!amount) {
      alert('Enter a non-zero amount (negative to deduct).');
      return;
    }

    // Look up the currently selected chat's user_id from the DOM data we
    // rendered the balance box for, via a fresh inbox fetch's selected payload.
    ajax('sbc_admin_get_inbox', {
      selected_chat_id: selectedChatId,
      selected_customer_key: selectedCustomerKey
    }).done(function (res) {
      const selected = res && res.data && res.data.selected;
      if (!selected || !selected.user_id) {
        alert('This chat is not linked to a registered user.');
        return;
      }

      ajax('sbc_admin_adjust_balance', {
        user_id: selected.user_id,
        amount: amount,
        note: note
      }).done(function (r2) {
        if (!r2 || !r2.success) {
          alert((r2 && r2.data && r2.data.message) ? r2.data.message : 'Could not adjust balance.');
          return;
        }
        refreshInbox(true);
      });
    });
  });

  threadEl.on('click', '.sbc-refresh-transaction', function () {
    const btn = $(this).prop('disabled', true).text('Refreshing...');
    ajax('sbc_admin_refresh_transaction', { chat_id: selectedChatId }).done(function (res) {
      if (!res || !res.success) {
        alert((res && res.data && res.data.message) ? res.data.message : 'Could not refresh transaction.');
        btn.prop('disabled', false).text('↻ Refresh Transaction');
        return;
      }
      refreshInbox(true);
    });
  });

  threadEl.on('keydown', '#sbc-admin-reply', function (e) {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      threadEl.find('#sbc-admin-send').click();
    }
  });

  refreshInbox(true);
  clearInterval(poller);
  poller = setInterval(function () {
    refreshInbox(false);
  }, 2500);
});
