(function () {
  'use strict';

  /* ---------------- Header scroll + mobile nav ---------------- */
  const header = document.getElementById('siteHeader');
  const navToggle = document.getElementById('navToggle');
  const mainNav = document.getElementById('mainNav');

  window.addEventListener('scroll', () => {
    if (!header) return;
    header.classList.toggle('is-scrolled', window.scrollY > 12);
  }, { passive: true });

  if (navToggle && mainNav) {
    navToggle.addEventListener('click', () => {
      const open = mainNav.classList.toggle('is-open');
      navToggle.setAttribute('aria-expanded', open ? 'true' : 'false');
      document.body.style.overflow = open ? 'hidden' : '';
    });
    mainNav.querySelectorAll('a').forEach(a => a.addEventListener('click', () => {
      mainNav.classList.remove('is-open');
      navToggle.setAttribute('aria-expanded', 'false');
      document.body.style.overflow = '';
    }));
  }

  document.querySelectorAll('.has-mega > .nav-link').forEach(link => {
    link.addEventListener('click', (e) => {
      if (window.innerWidth > 980) return;
      e.preventDefault();
      link.parentElement.classList.toggle('is-open');
    });
  });

  /* ---------------- Scroll reveal ---------------- */
  const revealEls = document.querySelectorAll('.reveal');
  if ('IntersectionObserver' in window && revealEls.length) {
    const io = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          entry.target.classList.add('is-visible');
          io.unobserve(entry.target);
        }
      });
    }, { threshold: 0.12 });
    revealEls.forEach(el => io.observe(el));
  } else {
    revealEls.forEach(el => el.classList.add('is-visible'));
  }

  /* ---------------- Animated counters ---------------- */
  document.querySelectorAll('[data-counter]').forEach(el => {
    const target = parseFloat(el.getAttribute('data-counter'));
    const decimals = el.getAttribute('data-decimals') ? parseInt(el.getAttribute('data-decimals'), 10) : 0;
    const suffix = el.getAttribute('data-suffix') || '';
    const run = () => {
      const duration = 1400;
      const start = performance.now();
      const step = (now) => {
        const p = Math.min(1, (now - start) / duration);
        const eased = 1 - Math.pow(1 - p, 3);
        el.textContent = (target * eased).toFixed(decimals) + suffix;
        if (p < 1) requestAnimationFrame(step);
      };
      requestAnimationFrame(step);
    };
    if ('IntersectionObserver' in window) {
      const io = new IntersectionObserver((entries) => {
        entries.forEach(entry => { if (entry.isIntersecting) { run(); io.disconnect(); } });
      }, { threshold: 0.4 });
      io.observe(el);
    } else run();
  });

  /* ---------------- Accordion (FAQ) ---------------- */
  document.querySelectorAll('.accordion-trigger').forEach(trigger => {
    trigger.addEventListener('click', () => {
      const panel = document.getElementById(trigger.getAttribute('aria-controls'));
      const expanded = trigger.getAttribute('aria-expanded') === 'true';
      trigger.setAttribute('aria-expanded', expanded ? 'false' : 'true');
      if (panel) panel.style.maxHeight = expanded ? '0px' : panel.scrollHeight + 'px';
    });
  });

  /* ---------------- Tabs ---------------- */
  document.querySelectorAll('.tabs-nav').forEach(nav => {
    const buttons = nav.querySelectorAll('button');
    buttons.forEach(btn => {
      btn.addEventListener('click', () => {
        const group = nav.closest('[data-tabs-group]') || document;
        buttons.forEach(b => b.classList.remove('active'));
        btn.classList.add('active');
        group.querySelectorAll('.tab-panel').forEach(p => p.classList.remove('active'));
        const panel = document.getElementById(btn.getAttribute('data-tab'));
        if (panel) panel.classList.add('active');
      });
    });
  });

  /* ---------------- Lightbox gallery ---------------- */
  const lightbox = document.querySelector('.lightbox');
  if (lightbox) {
    const imgEl = lightbox.querySelector('img');
    const counterEl = lightbox.querySelector('.lb-counter');
    let gallery = [];
    let idx = 0;

    const show = (i) => {
      idx = (i + gallery.length) % gallery.length;
      imgEl.src = gallery[idx];
      if (counterEl) counterEl.textContent = (idx + 1) + ' / ' + gallery.length;
    };

    document.querySelectorAll('[data-gallery] [data-full]').forEach((trigger, i, all) => {
      trigger.addEventListener('click', (e) => {
        e.preventDefault();
        gallery = Array.from(all).map(a => a.getAttribute('data-full'));
        show(i);
        lightbox.classList.add('is-open');
        document.body.style.overflow = 'hidden';
      });
    });

    lightbox.querySelector('.lb-close')?.addEventListener('click', close);
    lightbox.addEventListener('click', (e) => { if (e.target === lightbox) close(); });
    lightbox.querySelector('.lb-prev')?.addEventListener('click', () => show(idx - 1));
    lightbox.querySelector('.lb-next')?.addEventListener('click', () => show(idx + 1));
    document.addEventListener('keydown', (e) => {
      if (!lightbox.classList.contains('is-open')) return;
      if (e.key === 'Escape') close();
      if (e.key === 'ArrowLeft') show(idx - 1);
      if (e.key === 'ArrowRight') show(idx + 1);
    });
    function close() {
      lightbox.classList.remove('is-open');
      document.body.style.overflow = '';
    }
  }

  /* ---------------- Toast ---------------- */
  function toast(message) {
    let t = document.querySelector('.toast');
    if (!t) {
      t = document.createElement('div');
      t.className = 'toast';
      document.body.appendChild(t);
    }
    t.textContent = message;
    t.classList.add('is-visible');
    clearTimeout(t._timer);
    t._timer = setTimeout(() => t.classList.remove('is-visible'), 2600);
  }
  window.kyToast = toast;

  /* ---------------- Favorites (localStorage) ---------------- */
  const FAV_KEY = 'ky_favorites';
  const getFavorites = () => JSON.parse(localStorage.getItem(FAV_KEY) || '[]');
  const setFavorites = (arr) => localStorage.setItem(FAV_KEY, JSON.stringify(arr));

  function refreshFavButtons() {
    const favs = getFavorites();
    document.querySelectorAll('.fav-btn[data-id]').forEach(btn => {
      const id = btn.getAttribute('data-id');
      btn.classList.toggle('is-active', favs.includes(id));
      btn.setAttribute('aria-pressed', favs.includes(id) ? 'true' : 'false');
    });
  }
  document.addEventListener('click', (e) => {
    const btn = e.target.closest('.fav-btn[data-id]');
    if (!btn) return;
    e.preventDefault();
    const id = btn.getAttribute('data-id');
    let favs = getFavorites();
    if (favs.includes(id)) {
      favs = favs.filter(f => f !== id);
      toast('Removed from Saved Homes');
    } else {
      favs.push(id);
      toast('Saved to your favorites');
    }
    setFavorites(favs);
    refreshFavButtons();
  });
  refreshFavButtons();
  window.kyFavorites = { get: getFavorites, set: setFavorites };

  /* ---------------- Compare (localStorage, max 3) ---------------- */
  const CMP_KEY = 'ky_compare';
  const getCompare = () => JSON.parse(localStorage.getItem(CMP_KEY) || '[]');
  const setCompare = (arr) => localStorage.setItem(CMP_KEY, JSON.stringify(arr));

  function refreshCompareButtons() {
    const list = getCompare();
    document.querySelectorAll('.compare-toggle[data-id]').forEach(btn => {
      const id = btn.getAttribute('data-id');
      const active = list.includes(id);
      btn.classList.toggle('active', active);
      btn.textContent = active ? 'Remove from Compare' : 'Add to Compare';
    });
  }
  document.addEventListener('click', (e) => {
    const btn = e.target.closest('.compare-toggle[data-id]');
    if (!btn) return;
    e.preventDefault();
    const id = btn.getAttribute('data-id');
    let list = getCompare();
    if (list.includes(id)) {
      list = list.filter(f => f !== id);
    } else {
      if (list.length >= 3) { toast('You can compare up to 3 properties'); return; }
      list.push(id);
    }
    setCompare(list);
    refreshCompareButtons();
  });
  refreshCompareButtons();
  window.kyCompare = { get: getCompare, set: setCompare };

  /* ---------------- Mortgage calculator ---------------- */
  document.querySelectorAll('[data-mortgage-calc]').forEach(calc => {
    const price = parseFloat(calc.getAttribute('data-price') || '0');
    const downInput = calc.querySelector('[name="down_payment_pct"]');
    const rateInput = calc.querySelector('[name="interest_rate"]');
    const termInput = calc.querySelector('[name="loan_term"]');
    const downOut = calc.querySelector('[data-out="down_payment_pct"]');
    const rateOut = calc.querySelector('[data-out="interest_rate"]');
    const termOut = calc.querySelector('[data-out="loan_term"]');
    const resultEl = calc.querySelector('[data-result="monthly"]');
    const principalEl = calc.querySelector('[data-result="principal"]');

    function fmt(n) { return Math.round(n).toLocaleString('en-US'); }

    function compute() {
      const downPct = parseFloat(downInput.value);
      const rate = parseFloat(rateInput.value) / 100 / 12;
      const months = parseFloat(termInput.value) * 12;
      const principal = price * (1 - downPct / 100);
      const monthly = rate === 0 ? principal / months : (principal * rate) / (1 - Math.pow(1 + rate, -months));
      if (downOut) downOut.textContent = downPct + '%';
      if (rateOut) rateOut.textContent = rateInput.value + '%';
      if (termOut) termOut.textContent = termInput.value + ' yrs';
      if (resultEl) resultEl.textContent = 'RWF ' + fmt(monthly);
      if (principalEl) principalEl.textContent = 'RWF ' + fmt(principal);
    }
    [downInput, rateInput, termInput].forEach(inp => inp && inp.addEventListener('input', compute));
    compute();
  });

  /* ---------------- ROI calculator ---------------- */
  document.querySelectorAll('[data-roi-calc]').forEach(calc => {
    const price = parseFloat(calc.getAttribute('data-price') || '0');
    const rentInput = calc.querySelector('[name="monthly_rent"]');
    const expenseInput = calc.querySelector('[name="annual_expense_pct"]');
    const yieldOut = calc.querySelector('[data-result="yield"]');
    const netOut = calc.querySelector('[data-result="net_annual"]');

    function compute() {
      const rent = parseFloat(rentInput.value || '0');
      const expensePct = parseFloat(expenseInput.value || '0');
      const annualGross = rent * 12;
      const annualNet = annualGross * (1 - expensePct / 100);
      const yieldPct = price > 0 ? (annualNet / price) * 100 : 0;
      if (yieldOut) yieldOut.textContent = yieldPct.toFixed(2) + '%';
      if (netOut) netOut.textContent = 'RWF ' + Math.round(annualNet).toLocaleString('en-US');
    }
    [rentInput, expenseInput].forEach(inp => inp && inp.addEventListener('input', compute));
    compute();
  });

  /* ---------------- Filter chips (toggle active + submit) ---------------- */
  document.querySelectorAll('.filter-chip[data-field]').forEach(chip => {
    chip.addEventListener('click', () => {
      const group = chip.closest('.filter-chip-row');
      const multi = group?.getAttribute('data-multi') === 'true';
      if (!multi) {
        group.querySelectorAll('.filter-chip').forEach(c => c.classList.remove('active'));
      }
      chip.classList.toggle('active');
    });
  });

  /* ---------------- Search instant suggest ---------------- */
  const searchInput = document.querySelector('[data-search-suggest]');
  if (searchInput) {
    const box = document.createElement('div');
    box.className = 'card';
    box.style.cssText = 'position:absolute;z-index:60;width:100%;margin-top:4px;max-height:320px;overflow:auto;display:none;';
    searchInput.parentElement.style.position = 'relative';
    searchInput.parentElement.appendChild(box);
    let timer;
    searchInput.addEventListener('input', () => {
      clearTimeout(timer);
      const q = searchInput.value.trim();
      if (q.length < 2) { box.style.display = 'none'; return; }
      timer = setTimeout(() => {
        fetch('/api/search-suggest.php?q=' + encodeURIComponent(q))
          .then(r => r.json())
          .then(items => {
            if (!items.length) { box.style.display = 'none'; return; }
            box.innerHTML = items.map(i => `<a href="${i.url}" style="display:block;padding:12px 16px;border-bottom:1px solid var(--color-border);font-size:14px;">${i.label}</a>`).join('');
            box.style.display = 'block';
          }).catch(() => {});
      }, 250);
    });
    document.addEventListener('click', (e) => { if (!box.contains(e.target) && e.target !== searchInput) box.style.display = 'none'; });
  }

  /* ---------------- Lazy image fade-in ---------------- */
  document.querySelectorAll('img[loading="lazy"]').forEach(img => {
    img.classList.add('lazy-img');
    if (img.complete) img.classList.add('is-loaded');
    else img.addEventListener('load', () => img.classList.add('is-loaded'));
  });

  /* ---------------- Newsletter / generic AJAX forms ---------------- */
  document.querySelectorAll('form[data-ajax]').forEach(form => {
    form.addEventListener('submit', (e) => {
      e.preventDefault();
      const btn = form.querySelector('button[type="submit"]');
      const originalText = btn ? btn.innerHTML : '';
      if (btn) { btn.disabled = true; btn.innerHTML = '<span class="spinner"></span>'; }
      fetch(form.action, { method: 'POST', body: new FormData(form), headers: { 'X-Requested-With': 'XMLHttpRequest' } })
        .then(r => r.json())
        .then(data => {
          toast(data.message || 'Thank you!');
          if (data.success) form.reset();
        })
        .catch(() => toast('Something went wrong. Please try again.'))
        .finally(() => { if (btn) { btn.disabled = false; btn.innerHTML = originalText; } });
    });
  });

})();
