/* ===== SHARED UTILITIES ===== */

const API = {
  base: '/api',

  getToken() { return localStorage.getItem('lf_token') || sessionStorage.getItem('lf_token'); },
  getUser() {
    try { return JSON.parse(localStorage.getItem('lf_user') || sessionStorage.getItem('lf_user') || 'null'); }
    catch { return null; }
  },

  async request(method, path, body = null) {
    const token = this.getToken();
    const opts = {
      method,
      headers: { 'Content-Type': 'application/json' }
    };
    if (token) opts.headers['Authorization'] = `Bearer ${token}`;
    if (body) opts.body = JSON.stringify(body);

    const res = await fetch(this.base + path, opts);
    const data = await res.json().catch(() => ({}));
    if (!res.ok) throw new Error(data.error || `Request failed (${res.status})`);
    return data;
  },

  get(path) { return this.request('GET', path); },
  post(path, body) { return this.request('POST', path, body); },
  put(path, body) { return this.request('PUT', path, body); },
  delete(path) { return this.request('DELETE', path); }
};

// Auth guards
function requireAuth() {
  const token = API.getToken();
  const user = API.getUser();
  if (!token || !user) {
    window.location.href = '/login.html';
    return null;
  }
  return user;
}

function requireAdmin() {
  const user = requireAuth();
  if (user && user.role !== 'admin') {
    showToast('Admin access required', 'error');
    window.location.href = '/dashboard.html';
    return null;
  }
  return user;
}

function logout() {
  const token = API.getToken();
  if (token) {
    fetch('/api/auth/logout', {
      method: 'POST',
      headers: { 'Authorization': `Bearer ${token}` }
    }).catch(() => {});
  }
  clearSession();
}

function clearSession() {
  localStorage.removeItem('lf_token');
  localStorage.removeItem('lf_user');
  sessionStorage.removeItem('lf_token');
  sessionStorage.removeItem('lf_user');
}

// Toast notifications
function showToast(message, type = 'info', duration = 3500) {
  let container = document.querySelector('.toast-container');
  if (!container) {
    container = document.createElement('div');
    container.className = 'toast-container';
    document.body.appendChild(container);
  }
  const icons = { success: '✓', error: '✕', warning: '⚠', info: 'ℹ' };
  const toast = document.createElement('div');
  toast.className = `toast toast-${type}`;
  toast.innerHTML = `<span>${icons[type] || 'ℹ'}</span>${message}`;
  container.appendChild(toast);
  setTimeout(() => toast.remove(), duration);
}

// Session timeout manager
class SessionManager {
  constructor(timeoutMinutes = 30) {
    this.timeout = timeoutMinutes * 60 * 1000;
    this.warningAt = 2 * 60 * 1000; // warn 2 min before
    this.timer = null;
    this.warnTimer = null;
    this.warningEl = null;
    this.events = ['click', 'keypress', 'mousemove', 'scroll', 'touchstart'];
    this.reset = this.reset.bind(this);
  }

  start() {
    this.events.forEach(e => document.addEventListener(e, this.reset, { passive: true }));
    this.schedule();
  }

  schedule() {
    clearTimeout(this.timer);
    clearTimeout(this.warnTimer);
    this.hideWarning();

    this.warnTimer = setTimeout(() => {
      this.showWarning();
    }, this.timeout - this.warningAt);

    this.timer = setTimeout(() => {
      this.hideWarning();
      showToast('Session expired. Redirecting to login...', 'warning');
      setTimeout(() => { logout(); window.location.href = '/login.html'; }, 1500);
    }, this.timeout);
  }

  reset() { this.schedule(); }

  showWarning() {
    if (!this.warningEl) {
      this.warningEl = document.createElement('div');
      this.warningEl.className = 'session-warning';
      this.warningEl.innerHTML = `
        ⚠ Your session will expire in <span id="countdown">2:00</span> due to inactivity.
        <button class="btn btn-orange btn-sm" onclick="sessionMgr.reset()">Stay Logged In</button>
      `;
      document.body.appendChild(this.warningEl);

      let secs = 120;
      const cd = setInterval(() => {
        secs--;
        const el = document.getElementById('countdown');
        if (el) el.textContent = `${Math.floor(secs/60)}:${String(secs%60).padStart(2,'0')}`;
        if (secs <= 0) clearInterval(cd);
      }, 1000);
    }
    this.warningEl.classList.add('show');
  }

  hideWarning() {
    if (this.warningEl) { this.warningEl.classList.remove('show'); }
  }

  stop() {
    this.events.forEach(e => document.removeEventListener(e, this.reset));
    clearTimeout(this.timer);
    clearTimeout(this.warnTimer);
  }
}

// Populate sidebar with user info
function initSidebar(activeLink) {
  const user = requireAuth();
  if (!user) return;

  // Set user info in sidebar
  const avatarEl = document.getElementById('sidebar-avatar');
  const nameEl = document.getElementById('sidebar-name');
  const roleEl = document.getElementById('sidebar-role');
  if (avatarEl) avatarEl.textContent = user.full_name.charAt(0).toUpperCase();
  if (nameEl) nameEl.textContent = user.full_name;
  if (roleEl) roleEl.textContent = user.role;

  // Show/hide admin items
  const adminItems = document.querySelectorAll('.admin-only');
  adminItems.forEach(el => { el.style.display = user.role === 'admin' ? 'flex' : 'none'; });

  // Mark active nav item
  if (activeLink) {
    const links = document.querySelectorAll('.nav-item');
    links.forEach(l => {
      if (l.getAttribute('href') === activeLink || l.dataset.page === activeLink) {
        l.classList.add('active');
      }
    });
  }

  // Mobile menu toggle
  const menuBtn = document.querySelector('.mobile-menu-btn');
  const sidebar = document.querySelector('.sidebar');
  if (menuBtn && sidebar) {
    menuBtn.addEventListener('click', () => sidebar.classList.toggle('open'));
    document.addEventListener('click', e => {
      if (!sidebar.contains(e.target) && !menuBtn.contains(e.target)) {
        sidebar.classList.remove('open');
      }
    });
  }

  // Logout button
  const logoutBtns = document.querySelectorAll('.logout-btn');
  logoutBtns.forEach(btn => {
    btn.addEventListener('click', (e) => {
      e.preventDefault();
      logout();
      window.location.href = '/login.html';
    });
  });

  // Load notification badge
  loadNotifBadge();

  return user;
}

async function loadNotifBadge() {
  try {
    const data = await API.get('/users/notifications');
    const badge = document.querySelector('.notif-count');
    if (badge) {
      badge.textContent = data.unread || '';
      badge.style.display = data.unread > 0 ? 'inline-flex' : 'none';
    }
    const navBadge = document.getElementById('notif-nav-badge');
    if (navBadge) {
      navBadge.textContent = data.unread || '';
      navBadge.style.display = data.unread > 0 ? 'block' : 'none';
    }
  } catch {}
}

// Clear cache
function clearCache() {
  const keys = [];
  for (let i = 0; i < localStorage.length; i++) {
    const k = localStorage.key(i);
    if (!k.startsWith('lf_')) keys.push(k);
  }
  keys.forEach(k => localStorage.removeItem(k));
  sessionStorage.clear();
  if ('caches' in window) {
    caches.keys().then(names => names.forEach(n => caches.delete(n)));
  }
  showToast('Cache cleared successfully', 'success');
}

// Format date for display
function fmtDate(d) {
  if (!d) return '—';
  const dt = new Date(d);
  if (isNaN(dt)) return d;
  return dt.toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric' });
}

// Time ago
function timeAgo(d) {
  if (!d) return '';
  const diff = (Date.now() - new Date(d)) / 1000;
  if (diff < 60) return 'Just now';
  if (diff < 3600) return `${Math.floor(diff/60)}m ago`;
  if (diff < 86400) return `${Math.floor(diff/3600)}h ago`;
  return `${Math.floor(diff/86400)}d ago`;
}

// Days until date
function daysUntil(dateStr) {
  if (!dateStr) return null;
  const diff = (new Date(dateStr) - new Date()) / (1000 * 3600 * 24);
  return Math.ceil(diff);
}

window.API = API;
window.requireAuth = requireAuth;
window.requireAdmin = requireAdmin;
window.logout = logout;
window.clearSession = clearSession;
window.showToast = showToast;
window.SessionManager = SessionManager;
window.initSidebar = initSidebar;
window.clearCache = clearCache;
window.fmtDate = fmtDate;
window.timeAgo = timeAgo;
window.daysUntil = daysUntil;
