const routes = new Map();
let currentScreen = null;
let mainEl = null;

export function register(path, screenFn) {
  routes.set(path, screenFn);
}

export function navigate(path, params = {}, replace = false) {
  const url = new URL(path, window.location.origin);
  Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v));

  if (replace) {
    history.replaceState({ path, params }, '', url);
  } else {
    history.pushState({ path, params }, '', url);
  }
  render(path, params);
}

export function init(container) {
  mainEl = container;

  window.addEventListener('popstate', (e) => {
    const s = e.state || {};
    render(s.path || location.pathname, s.params || Object.fromEntries(new URLSearchParams(location.search)));
  });

  document.addEventListener('click', (e) => {
    const link = e.target.closest('a[href]');
    if (!link) return;
    const href = link.getAttribute('href');
    if (!href || href.startsWith('http') || href.startsWith('#') || link.target === '_blank') return;
    if (href.startsWith('/api/')) return;
    e.preventDefault();
    navigate(href);
  });

  const path = location.pathname;
  const params = Object.fromEntries(new URLSearchParams(location.search));
  history.replaceState({ path, params }, '', location.href);
  render(path, params);
}

async function render(path, params = {}) {
  const screenFn = matchRoute(path);
  if (!screenFn) {
    mainEl.innerHTML = '<div class="empty">الصفحة غير موجودة</div>';
    return;
  }

  if (currentScreen && currentScreen.destroy) {
    mainEl.firstElementChild?.classList.add('screen-exit');
    await sleep(150);
    currentScreen.destroy();
  }

  mainEl.innerHTML = '';
  const screen = await screenFn(params);
  currentScreen = screen;

  const wrapper = document.createElement('div');
  wrapper.className = 'screen main-inner';
  mainEl.appendChild(wrapper);

  if (screen.render) {
    const html = screen.render(params);
    wrapper.innerHTML = html;
  }
  if (screen.mount) {
    await screen.mount(wrapper, params);
  }
}

function matchRoute(path) {
  const clean = path.replace(/\/$/, '') || '/';
  if (routes.has(clean)) return routes.get(clean);
  for (const [pattern, fn] of routes) {
    if (pattern.includes(':')) {
      const regex = new RegExp('^' + pattern.replace(/:([^/]+)/g, '([^/]+)') + '$');
      if (regex.test(clean)) return fn;
    }
  }
  return null;
}

function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }

export function getParams() {
  return Object.fromEntries(new URLSearchParams(location.search));
}
