function sanitizeNick(n){ return (n||'').toLowerCase().replace(/[^a-z0-9_]/g,'').slice(0,10); }
function me(){ return localStorage.getItem('chat_nick') || ''; }
let currentPrivate = '';

async function api(url, method='GET', body=null) {
  const opts = { method };
  if (body instanceof FormData) opts.body = body;
  else if (body) { opts.headers = {'Content-Type':'application/json'}; opts.body = JSON.stringify(body); }
  const res = await fetch(url, opts);
  const data = await res.json();
  if (!res.ok) throw new Error(data.error || 'Chyba');
  return data;
}

async function registerUser() {
  try {
    await api('/api/register', 'POST', {
      nick: regNick.value, password: regPass.value, password2: regPass2.value,
      pin: regPin.value, pin2: regPin2.value
    });
    alert('Registrácia úspešná');
  } catch(e) { alert(e.message); }
}

async function loginUser() {
  try {
    const data = await api('/api/login', 'POST', {
      nick: loginNick.value, password: loginPass.value
    });
    localStorage.setItem('chat_nick', data.nick);
    initChat();
  } catch(e) { alert(e.message); }
}

async function resetPassword() {
  try {
    await api('/api/reset-password', 'POST', {
      nick: resetNick.value, pin: resetPin.value,
      password: resetPass.value, password2: resetPass2.value
    });
    alert('Heslo bolo zmenené');
  } catch(e) { alert(e.message); }
}

function initChat() {
  document.getElementById('auth').style.display = 'none';
  document.getElementById('chat').style.display = 'block';
  document.getElementById('me').textContent = me();
  refreshAll();
  setInterval(refreshAll, 30000);
  setInterval(() => api('/api/ping', 'POST', {nick: me()}).catch(()=>{}), 5000);
}

async function refreshAll() {
  await loadPublic();
  await loadOnline();
  if (currentPrivate) await loadPrivate();
}

async function loadOnline() {
  const users = await api('/api/online?me=' + encodeURIComponent(me()));
  onlineUsers.innerHTML = users.map(u =>
    `<div><button onclick="selectPrivate('${u}')">${u}</button></div>`
  ).join('');
}

function selectPrivate(nick) {
  currentPrivate = nick;
  privateWith.textContent = nick;
  loadPrivate();
}

async function loadPublic() {
  const msgs = await api('/api/public');
  render(publicMessages, msgs);
}

async function loadPrivate() {
  if (!currentPrivate) return;
  const msgs = await api('/api/private/' + currentPrivate + '?me=' + encodeURIComponent(me()));
  render(privateMessages, msgs);
}
/*
function render(el, msgs) {
  el.innerHTML = msgs.map(m => {
    const img = m.image ? `<div><img src="${m.image}" class="chatimg"></div>` : '';
    return `<div><b>${escapeHtml(m.nick)}</b>: ${escapeHtml(m.text || '')}${img}</div>`;
  }).join('');
  el.scrollTop = el.scrollHeight;
}


function render(el, msgs) {
  // zisti, či je používateľ pri spodku (do 50 px od konca)
  const nearBottom =
    el.scrollHeight - el.scrollTop - el.clientHeight < 50;

  el.innerHTML = msgs.map(m => {
    const img = m.image
      ? `<div><img src="${m.image}" class="chatimg"></div>`
      : '';

    return `<div><b>${escapeHtml(m.nick)}</b>: ${escapeHtml(m.text || '')}${img}</div>`;
  }).join('');

  // automaticky scrolluj len ak bol používateľ pri spodku
  if (nearBottom) {
    el.scrollTop = el.scrollHeight;
  }
}
*/
function render(el, msgs) {
  // 1. Zapamätaj si aktuálnu pozíciu scrollu
  const oldScrollTop = el.scrollTop;
  const oldScrollHeight = el.scrollHeight;

  // 2. Zisti, či je používateľ pri spodku (do 50 px od konca)
  const nearBottom =
    oldScrollHeight - oldScrollTop - el.clientHeight < 50;

  // 3. Vykresli správy
  el.innerHTML = msgs.map(m => {
    const img = m.image
      ? `<div><img src="${m.image}" class="chatimg" loading="lazy"></div>`
      : '';

    return `
      <div class="msg">
        <b>${escapeHtml(m.nick)}</b>: ${escapeHtml(m.text || '')}
        ${img}
      </div>
    `;
  }).join('');

  // 4. Funkcia, ktorá nastaví správnu pozíciu scrollu
  const restoreScroll = () => {
    if (nearBottom) {
      // Ak bol používateľ na konci, zostaň na konci
      el.scrollTop = el.scrollHeight;
    } else {
      // Inak zachovaj približne rovnakú pozíciu
      const newScrollHeight = el.scrollHeight;
      const delta = newScrollHeight - oldScrollHeight;
      el.scrollTop = oldScrollTop + delta;
    }
  };

  // 5. Počkaj na načítanie všetkých obrázkov
  const images = Array.from(el.querySelectorAll('img'));

  if (images.length === 0) {
    restoreScroll();
    return;
  }

  let remaining = images.length;
  let finished = false;

  const done = () => {
    remaining--;
    if (remaining <= 0 && !finished) {
      finished = true;
      restoreScroll();
    }
  };

  // Bezpečnostná poistka – ak by sa nejaký obrázok nenačítal
  setTimeout(() => {
    if (!finished) {
      finished = true;
      restoreScroll();
    }
  }, 30000);

  images.forEach(img => {
    if (img.complete) {
      done();
    } else {
      img.addEventListener('load', done, { once: true });
      img.addEventListener('error', done, { once: true });
    }
  });
}

function escapeHtml(s) {
  const d = document.createElement('div');
  d.textContent = s;
  return d.innerHTML;
}

function addEmoji(e, target = 'public') {
  const input = target === 'private' ? privateText : publicText;
  input.value += e;
  input.focus();
}

async function sendPublic() {
  const fd = new FormData();
  fd.append('nick', me());
  fd.append('text', publicText.value);
  if (publicImage.files[0]) fd.append('image', publicImage.files[0]);
  await api('/api/public', 'POST', fd);
  publicText.value = '';
  publicImage.value = '';
  loadPublic();
}

async function sendPrivate() {
  if (!currentPrivate) return alert('Vyber používateľa.');
  const fd = new FormData();
  fd.append('me', me());
  fd.append('text', privateText.value);
  if (privateImage.files[0]) fd.append('image', privateImage.files[0]);
  await api('/api/private/' + currentPrivate, 'POST', fd);
  privateText.value = '';
  privateImage.value = '';
  loadPrivate();
}

if (me()) initChat();

async function logoutUser() {
  try {
    await api('/api/logout', 'POST', { nick: me() });
  } catch (e) {}
  localStorage.removeItem('chat_nick');
  location.reload();
}

window.addEventListener('beforeunload', function () {
  const nick = me();
  if (!nick) return;
  const data = JSON.stringify({ nick });
  if (navigator.sendBeacon) {
    navigator.sendBeacon('/api/logout', new Blob([data], { type: 'application/json' }));
  }
});


let lastPublicCount = 0;
let lastPrivateCount = 0;
let audioCtx = null;

function beep() {
  try {
    if (!audioCtx) audioCtx = new (window.AudioContext || window.webkitAudioContext)();
    const osc = audioCtx.createOscillator();
    const gain = audioCtx.createGain();
    osc.connect(gain);
    gain.connect(audioCtx.destination);
    osc.frequency.value = 880;
    gain.gain.value = 0.05;
    osc.start();
    osc.stop(audioCtx.currentTime + 0.12);
  } catch (e) {}
}

const originalLoadPublic = loadPublic;
loadPublic = async function() {
  const msgs = await api('/api/public');
  render(publicMessages, msgs);
  if (lastPublicCount && msgs.length > lastPublicCount) beep();
  lastPublicCount = msgs.length;
};

const originalLoadPrivate = loadPrivate;
loadPrivate = async function() {
  if (!currentPrivate) return;
  const msgs = await api('/api/private/' + currentPrivate + '?me=' + encodeURIComponent(me()));
  render(privateMessages, msgs);
  if (lastPrivateCount && msgs.length > lastPrivateCount) beep();
  lastPrivateCount = msgs.length;
};





function toggleEmojiPicker(target) {
  const picker = document.getElementById(target === 'private' ? 'privatePicker' : 'publicPicker');
  picker.classList.toggle('hidden');
}

function setupEmojiPickers() {
  const publicPicker = document.getElementById('publicPicker');
  const privatePicker = document.getElementById('privatePicker');

  if (publicPicker) {
    publicPicker.addEventListener('emoji-click', event => {
      addEmoji(event.detail.unicode, 'public');
      publicPicker.classList.add('hidden');
    });
  }

  if (privatePicker) {
    privatePicker.addEventListener('emoji-click', event => {
      addEmoji(event.detail.unicode, 'private');
      privatePicker.classList.add('hidden');
    });
  }
}

function applyTheme(theme) {
  document.documentElement.setAttribute('data-theme', theme);
  const btn = document.getElementById('themeToggle');
  if (btn) {
    btn.textContent = theme === 'dark' ? '☀️ Light Mode' : '🌙 Dark Mode';
  }
}

function toggleTheme() {
  const current = localStorage.getItem('chat_theme') || 'light';
  const next = current === 'dark' ? 'light' : 'dark';
  localStorage.setItem('chat_theme', next);
  applyTheme(next);
}

document.addEventListener('DOMContentLoaded', () => {
  applyTheme(localStorage.getItem('chat_theme') || 'light');
  setupEmojiPickers();
});
