(function () {
  function escapeHtml(value) {
    return String(value || '')
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/\"/g, '&quot;')
      .replace(/'/g, '&#039;');
  }

  function renderMessage(message, currentUserId) {
    var ownClass = Number(message.user_id) === Number(currentUserId) ? ' kgvvm-chat-message--own' : '';
    var roleLabel = message.role ? ' · ' + escapeHtml(message.role) : '';
    var text = escapeHtml(message.message).replace(/\n/g, '<br>');

    return '' +
      '<article class="kgvvm-chat-message' + ownClass + '" data-id="' + escapeHtml(message.id) + '">' +
        '<div class="kgvvm-chat-message__meta">' +
          '<strong>' + escapeHtml(message.user) + '</strong>' + roleLabel + ' · ' + escapeHtml(message.time) +
        '</div>' +
        '<div class="kgvvm-chat-message__body">' + text + '</div>' +
      '</article>';
  }

  document.addEventListener('DOMContentLoaded', function () {
    var app = document.querySelector('.kgvvm-chat-app');

    if (!app || typeof window.kgvvmChatConfig === 'undefined') {
      return;
    }

    var config = window.kgvvmChatConfig;
    var messagesEl = app.querySelector('[data-chat-messages]');
    var form = app.querySelector('[data-chat-form]');
    var input = app.querySelector('[data-chat-input]');
    var status = app.querySelector('[data-chat-status]');
    var roomButtons = app.querySelectorAll('[data-chat-room]');
    var roomTitle = app.querySelector('[data-chat-room-title]');
    var roomDescription = app.querySelector('[data-chat-room-description]');
    var currentRoom = app.getAttribute('data-room') || 'general';
    var initialRoom = currentRoom;
    var currentUserId = Number(app.getAttribute('data-current-user-id') || '0');
    var sendLocked = false;
    var storageKey = 'kgvvmActiveChatRoom';

    function getAvailableRooms() {
      return Array.prototype.map.call(roomButtons, function (button) {
        return button.getAttribute('data-chat-room') || '';
      }).filter(Boolean);
    }

    function syncRoomState() {
      try {
        window.localStorage.setItem(storageKey, currentRoom);
      } catch (error) {
        // ignore storage errors
      }

      if (window.history && typeof window.history.replaceState === 'function') {
        var url = new window.URL(window.location.href);
        url.searchParams.set('room', currentRoom);
        window.history.replaceState({}, '', url.toString());
      }
    }

    function restoreRoomState() {
      var availableRooms = getAvailableRooms();
      var url = new window.URL(window.location.href);
      var requestedRoom = url.searchParams.get('room') || '';
      var storedRoom = '';

      try {
        storedRoom = window.localStorage.getItem(storageKey) || '';
      } catch (error) {
        storedRoom = '';
      }

      var preferredRoom = requestedRoom || storedRoom;

      if (preferredRoom && availableRooms.indexOf(preferredRoom) !== -1) {
        currentRoom = preferredRoom;
        app.setAttribute('data-room', currentRoom);
      }
    }

    function setStatus(text, isError) {
      if (!status) {
        return;
      }

      status.textContent = text || '';
      status.classList.toggle('is-error', !!isError);
    }

    function scrollToBottom() {
      if (messagesEl) {
        messagesEl.scrollTop = messagesEl.scrollHeight;
      }
    }

    function updateRoomButtons() {
      roomButtons.forEach(function (button) {
        button.classList.toggle('is-active', button.getAttribute('data-chat-room') === currentRoom);
      });
    }

    function updateRoomMeta() {
      roomButtons.forEach(function (button) {
        if (button.getAttribute('data-chat-room') !== currentRoom) {
          return;
        }

        if (roomTitle) {
          roomTitle.textContent = button.getAttribute('data-chat-label') || '';
        }

        if (roomDescription) {
          roomDescription.textContent = button.getAttribute('data-chat-description') || '';
        }
      });
    }

    function renderMessages(messages, replaceAll) {
      if (!messagesEl) {
        return;
      }

      if (replaceAll) {
        messagesEl.innerHTML = '';
      }

      if (!Array.isArray(messages) || !messages.length) {
        if (replaceAll) {
          messagesEl.innerHTML = '<p class="kgvvm-chat-empty">' + escapeHtml(config.i18n.empty) + '</p>';
          messagesEl.dataset.lastId = '0';
        }
        return;
      }

      if (messagesEl.querySelector('.kgvvm-chat-empty')) {
        messagesEl.innerHTML = '';
      }

      messages.forEach(function (message) {
        messagesEl.insertAdjacentHTML('beforeend', renderMessage(message, currentUserId));
        messagesEl.dataset.lastId = String(message.id || messagesEl.dataset.lastId || '0');
      });

      scrollToBottom();
    }

    function fetchMessages(replaceAll) {
      var data = new window.FormData();
      data.append('action', 'kgvvm_fetch_chat_messages');
      data.append('nonce', config.nonce);
      data.append('room', currentRoom);

      if (!replaceAll && messagesEl && messagesEl.dataset.lastId) {
        data.append('after_id', messagesEl.dataset.lastId);
      }

      return window.fetch(config.ajaxUrl, {
        method: 'POST',
        credentials: 'same-origin',
        body: data
      })
        .then(function (response) { return response.json(); })
        .then(function (payload) {
          if (!payload || !payload.success) {
            return;
          }

          renderMessages(payload.data.messages || [], replaceAll);
        })
        .catch(function () {
          setStatus(config.i18n.fetchError, true);
        });
    }

    roomButtons.forEach(function (button) {
      button.addEventListener('click', function () {
        currentRoom = button.getAttribute('data-chat-room') || 'general';
        app.setAttribute('data-room', currentRoom);
        syncRoomState();
        updateRoomMeta();

        if (messagesEl) {
          messagesEl.dataset.lastId = '0';
        }

        updateRoomButtons();
        setStatus(config.i18n.loading, false);
        fetchMessages(true).then(function () {
          setStatus('', false);
        });
      });
    });

    if (form && input) {
      form.addEventListener('submit', function (event) {
        event.preventDefault();

        if (sendLocked) {
          return;
        }

        var message = String(input.value || '').trim();

        if (!message) {
          return;
        }

        sendLocked = true;
        setStatus(config.i18n.sending, false);

        var data = new window.FormData();
        data.append('action', 'kgvvm_send_chat_message');
        data.append('nonce', config.nonce);
        data.append('room', currentRoom);
        data.append('message', message);

        window.fetch(config.ajaxUrl, {
          method: 'POST',
          credentials: 'same-origin',
          body: data
        })
          .then(function (response) { return response.json(); })
          .then(function (payload) {
            sendLocked = false;

            if (!payload || !payload.success) {
              setStatus(config.i18n.sendError, true);
              return;
            }

            renderMessages(payload.data.messages || [], false);
            input.value = '';
            input.focus();
            setStatus('', false);
          })
          .catch(function () {
            sendLocked = false;
            setStatus(config.i18n.sendError, true);
          });
      });
    }

    restoreRoomState();
    updateRoomButtons();
    updateRoomMeta();
    syncRoomState();

    if (currentRoom !== initialRoom) {
      fetchMessages(true);
    }

    scrollToBottom();
    window.setInterval(function () {
      fetchMessages(false);
    }, Number(config.refreshInterval || 7000));
  });
})();
