const GUESTBOOK_API = 'https://guestbook.bug-dev-mail.workers.dev';

const EMOTES = {
  ':happy:':  'images/emotes/joy.gif',
  ':love:':   'images/emotes/love.gif',
  ':laugh:':  'images/emotes/laugh.gif',
  ':shock:':  'images/emotes/astonished.gif',
  ':hello:':  'images/emotes/wave.gif',
  ':kiss:':   'images/emotes/kiss.gif',
  ':clap:':   'images/emotes/applause.gif',
  ':dance:':  'images/emotes/caramelldansen.gif',
  ':yippee:': 'images/emotes/yippee.gif',
};

function replaceLinks(text) {
  function cleanUrl(url) {
    return url.replace(/&amp;/g, '&');
  }
  var result = text.replace(/\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)/g,
    function(_, label, url) {
      return '<a href="' + cleanUrl(url) + '" target="_blank" rel="noopener noreferrer">' + label + '</a>';
    });
  result = result.replace(/(^|[^"'])(https?:\/\/[^\s<]+)/g,
    function(_, pre, url) {
      return pre + '<a href="' + cleanUrl(url) + '" target="_blank" rel="noopener noreferrer">' + url + '</a>';
    });
  return result;
}

function replaceEmotes(text) {
  let result = replaceLinks(text);
  for (const [code, src] of Object.entries(EMOTES)) {
    const escaped = code.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    result = result.replace(new RegExp(escaped, 'g'),
      `<img src="${src}" class="gb-emote" title="${code}" alt="${code}">`);
  }
  return result;
}

function timeAgo(dateStr) {
  if (!dateStr.includes('T') && !dateStr.includes('-')) {
    return dateStr;
  }
  const d = new Date(dateStr);
  const now = new Date();
  const diffMs = now - d;
  const diffMin = Math.floor(diffMs / 60000);
  const diffHr = Math.floor(diffMs / 3600000);
  const diffDay = Math.floor(diffMs / 86400000);

  if (diffMin < 1) return 'just now';
  if (diffMin < 60) return diffMin + ' min ago';
  if (diffHr < 24) return diffHr + ' hr ago';
  if (diffDay === 1) return '1 day ago';
  return diffDay + ' days ago';
}

function createMessageBubble(msg) {
  const entry = document.createElement('div');
  entry.style.setProperty('--col', '#90c9ff');

  const nameDiv = document.createElement('div');
  nameDiv.textContent = msg.name || 'Anonymous';

  const dateDiv = document.createElement('div');
  dateDiv.className = 'gb-date';
  dateDiv.textContent = timeAgo(msg.date);

  const msgDiv = document.createElement('div');
  msgDiv.className = 'gb-msg-content';
  msgDiv.innerHTML = replaceEmotes(msg.message);

  entry.appendChild(nameDiv);
  entry.appendChild(dateDiv);
  entry.appendChild(msgDiv);

  const actions = document.createElement('div');
  actions.className = 'gb-actions';

  const likeBtn = document.createElement('button');
  likeBtn.className = 'gb-like-btn';
  const likeCount = typeof msg.likes === 'number' ? msg.likes : (Array.isArray(msg.likes) ? msg.likes.length : 0);
  likeBtn.innerHTML = `<span class="gb-like-icon">&hearts;</span> ${likeCount}`;
  likeBtn.onclick = () => likeMessage(msg.id, likeBtn);

  actions.appendChild(likeBtn);
  entry.appendChild(actions);

  return entry;
}

async function loadMessages() {
  const picto = document.querySelector('#pictochat-content .picto');
  if (!picto) return;
  picto.innerHTML = '';

  try {
    const res = await fetch(GUESTBOOK_API + '/messages');
    const messages = await res.json();
    messages.forEach(msg => {
      picto.appendChild(createMessageBubble(msg));
    });
  } catch (e) {
    const err = document.createElement('div');
    err.style.setProperty('--col', '#90c9ff');
    const nameDiv = document.createElement('div');
    nameDiv.textContent = 'system';
    const msgDiv = document.createElement('div');
    msgDiv.textContent = 'No one has commented yet. Be the first!';
    err.appendChild(nameDiv);
    err.appendChild(document.createTextNode(''));
    err.appendChild(document.createElement('br'));
    err.appendChild(msgDiv);
    picto.appendChild(err);
  }
}

async function sendMessage() {
  const nameInput = document.getElementById('gb-name');
  const msgInput = document.getElementById('gb-message');
  const sendBtn = document.getElementById('gb-send');

  const message = msgInput.value.trim();
  if (!message) return;

  sendBtn.classList.add('gb-disabled');
  try {
    await fetch(GUESTBOOK_API + '/messages', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        name: nameInput.value.trim() || 'Anonymous',
        message: message,
      }),
    });
    msgInput.value = '';
    await loadMessages();
    setTimeout(replaceTextWithEmotes, 500);
  } catch (e) {

  }
  sendBtn.classList.remove('gb-disabled');
}

async function likeMessage(id, btn) {
  try {
    const res = await fetch(GUESTBOOK_API + `/messages/${id}/like`, { method: 'POST' });
    const data = await res.json();
    btn.innerHTML = `<span class="gb-like-icon">&hearts;</span> ${data.likes}`;
    btn.classList.add('gb-liked');
  } catch (e) {

  }
}

function toggleEmoteSelector() {
  const els = document.getElementsByClassName('gb-toggle-div');
  for (let i = 0; i < els.length; i++) {
    if (els[i].style.display === 'none' || els[i].style.display === '') {
      els[i].style.display = 'block';
    } else {
      els[i].style.display = 'none';
    }
  }
}

function addText(text) {
  const textarea = document.getElementById('gb-message');
  textarea.value += text;
  textarea.focus();
}

function replaceTextWithEmotes() {
  const picto = document.querySelector('#pictochat-content .picto');
  if (!picto) return;

  function replaceTextNodes(element) {
    element.childNodes.forEach(function (node) {
      if (node.nodeType === Node.TEXT_NODE) {
        let replacedText = node.textContent;
        let changed = false;
        for (const [key, src] of Object.entries(EMOTES)) {
          const escapedKey = key.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
          const imgTag = "<img src='" + src + "' title='" + key + "' class='gb-emote' />";
          const newText = replacedText.replace(new RegExp(escapedKey, 'g'), imgTag);
          if (newText !== replacedText) {
            replacedText = newText;
            changed = true;
          }
        }
        if (changed) {
          const newElement = document.createElement('span');
          newElement.innerHTML = replacedText;
          node.parentNode.replaceChild(newElement, node);
        }
      } else {
        replaceTextNodes(node);
      }
    });
  }

  replaceTextNodes(picto);
}

(function () {
  const picto = document.querySelector('#pictochat-content .picto');
  if (!picto) return;

  const sendBtn = document.getElementById('gb-send');
  if (sendBtn) sendBtn.addEventListener('click', sendMessage);

  const msgInput = document.getElementById('gb-message');
  if (msgInput) {
    msgInput.addEventListener('keydown', (e) => {
      if (e.key === 'Enter' && !e.shiftKey) {
        e.preventDefault();
        sendMessage();
      }
    });
  }

  const emoteBtn = document.getElementById('gb-emote-toggle');
  if (emoteBtn) emoteBtn.addEventListener('click', toggleEmoteSelector);

  document.addEventListener('click', function (e) {
    const selector = document.getElementById('gb-emote-selector');
    const toggle = document.getElementById('gb-emote-toggle');
    if (selector && selector.style.display === 'block' &&
        !selector.contains(e.target) && e.target !== toggle) {
      selector.style.display = 'none';
    }
  });

  const emoteItems = document.querySelectorAll('#gb-emote-selector .gb-emote-item');
  emoteItems.forEach(function (img) {
    img.addEventListener('click', function () {
      addText(img.title + ' ');
    });
  });

  loadMessages().then(function () {
    replaceTextWithEmotes();
  });
})();
