/* ============================================================
   Gmind Institute — Main JavaScript
   Vanilla ES2022, no dependencies, no jQuery
   ============================================================ */

(() => {
  'use strict';

  /* ----------------------------------------------------------
     14. Utility Functions
     ---------------------------------------------------------- */

  /**
   * Debounce — delays invocation until after `delay` ms of inactivity.
   * Ideal for resize / scroll events where you only care about the
   * final value.
   *
   * @param {Function} fn     Callback to debounce
   * @param {number}   delay  Milliseconds to wait
   * @returns {Function}
   */
  const debounce = (fn, delay) => {
    let timer = null;
    return (...args) => {
      clearTimeout(timer);
      timer = setTimeout(() => fn(...args), delay);
    };
  };

  /**
   * Throttle — invokes `fn` at most once every `limit` ms.
   * Uses requestAnimationFrame for the leading-edge call so
   * the browser can batch with the next paint.
   *
   * @param {Function} fn     Callback to throttle
   * @param {number}   limit  Minimum ms between calls
   * @returns {Function}
   */
  const throttle = (fn, limit) => {
    let lastCall = 0;
    let rafId = null;
    return (...args) => {
      const now = Date.now();
      if (now - lastCall >= limit) {
        lastCall = now;
        if (rafId) cancelAnimationFrame(rafId);
        rafId = requestAnimationFrame(() => fn(...args));
      }
    };
  };

  /**
   * Check if the viewport is mobile-sized (< 768 px).
   * @returns {boolean}
   */
  const isMobile = () => window.innerWidth < 768;

  /* ----------------------------------------------------------
     1. Hero Slider
     ---------------------------------------------------------- */

  const initHeroSlider = () => {
    const slider = document.querySelector('.hero-banner-slider');
    if (!slider) return;

    const slides = [...slider.querySelectorAll('.hero-slide')];
    const dots = [...slider.querySelectorAll('.hero-dot')];
    const prevBtn = slider.querySelector('.hero-arrow-prev');
    const nextBtn = slider.querySelector('.hero-arrow-next');

    if (slides.length === 0) return;

    let current = 0;
    let autoTimer = null;
    let touchStartX = 0;

    /** Activate a specific slide by index */
    const goTo = (index) => {
      // Wrap around for infinite navigation
      if (index < 0) index = slides.length - 1;
      if (index >= slides.length) index = 0;

      slides[current]?.classList.remove('active');
      dots[current]?.classList.remove('active');

      current = index;

      slides[current]?.classList.add('active');
      dots[current]?.classList.add('active');
    };

    const next = () => goTo(current + 1);
    const prev = () => goTo(current - 1);

    /** Start auto-play (5 s interval) */
    const startAuto = () => {
      stopAuto();
      autoTimer = setInterval(next, 5000);
    };

    /** Stop auto-play */
    const stopAuto = () => {
      if (autoTimer) {
        clearInterval(autoTimer);
        autoTimer = null;
      }
    };

    // --- Arrow click handlers ---
    prevBtn?.addEventListener('click', () => { prev(); startAuto(); });
    nextBtn?.addEventListener('click', () => { next(); startAuto(); });

    // --- Dot indicator click handlers ---
    dots.forEach((dot, i) => {
      dot.addEventListener('click', () => { goTo(i); startAuto(); });
    });

    // --- Pause on hover ---
    slider.addEventListener('mouseenter', stopAuto);
    slider.addEventListener('mouseleave', startAuto);

    // --- Touch swipe support ---
    slider.addEventListener('touchstart', (e) => {
      touchStartX = e.changedTouches[0].screenX;
      stopAuto();
    }, { passive: true });

    slider.addEventListener('touchend', (e) => {
      const diff = e.changedTouches[0].screenX - touchStartX;
      if (Math.abs(diff) > 50) {
        diff > 0 ? prev() : next();
      }
      startAuto();
    }, { passive: true });

    // --- Keyboard accessibility ---
    slider.setAttribute('tabindex', '0');
    slider.addEventListener('keydown', (e) => {
      if (e.key === 'ArrowLeft') { prev(); startAuto(); }
      if (e.key === 'ArrowRight') { next(); startAuto(); }
    });

    // --- Initialise first slide & auto-play ---
    goTo(0);
    startAuto();
  };

  /* ----------------------------------------------------------
     2. Sticky Header
     ---------------------------------------------------------- */

  const initStickyHeader = () => {
    const header = document.querySelector('.main-nav');
    if (!header) return;

    const onScroll = () => {
      requestAnimationFrame(() => {
        if (window.scrollY > 80) {
          header.classList.add('scrolled');
        } else {
          header.classList.remove('scrolled');
        }
      });
    };

    window.addEventListener('scroll', throttle(onScroll, 100), { passive: true });
    // Run once on init in case the page loads already scrolled
    onScroll();
  };

  /* ----------------------------------------------------------
     3. Mobile Menu Toggle
     ---------------------------------------------------------- */

  const initMobileMenu = () => {
    const nav = document.querySelector('.main-nav');
    const toggle = document.querySelector('.nav-toggle');
    const links = document.querySelector('.nav-links');

    if (!nav || !toggle || !links) return;

    /** Open or close the mobile menu */
    const toggleMenu = () => {
      const isOpen = nav.classList.toggle('menu-open');
      toggle.checked = isOpen;
    };

    const closeMenu = () => {
      nav.classList.remove('menu-open');
      toggle.checked = false;
    };

    // Hamburger label click toggles via the checkbox — but we also
    // add a class on the <nav> so outside-click can close it.
    toggle.addEventListener('change', () => {
      if (toggle.checked) {
        nav.classList.add('menu-open');
      } else {
        nav.classList.remove('menu-open');
      }
    });

    // Click outside to close
    document.addEventListener('click', (e) => {
      if (nav.classList.contains('menu-open') && !nav.contains(e.target)) {
        closeMenu();
      }
    });

    // Click a regular nav link to close menu (smooth UX on mobile)
    // But NOT the "More" dropdown toggle — that should expand the submenu
    links.querySelectorAll('a:not(.nav-dropdown-toggle)').forEach((link) => {
      link.addEventListener('click', closeMenu);
    });

    // Handle "More" dropdown toggle on mobile — tap to open/close submenu
    const dropdownToggles = links.querySelectorAll('.nav-dropdown-toggle');
    dropdownToggles.forEach((toggleBtn) => {
      toggleBtn.addEventListener('click', (e) => {
        e.preventDefault();
        e.stopPropagation();
        const dropdown = toggleBtn.closest('.nav-dropdown');
        if (dropdown) {
          // Close any other open dropdowns first
          links.querySelectorAll('.nav-dropdown.open').forEach((dd) => {
            if (dd !== dropdown) dd.classList.remove('open');
          });
          dropdown.classList.toggle('open');
        }
      });
    });

    // Close submenu items when clicked (they are inside the dropdown menu)
    links.querySelectorAll('.nav-dropdown-menu a').forEach((link) => {
      link.addEventListener('click', closeMenu);
    });
  };

  /* ----------------------------------------------------------
     4. Stats Counter Animation
     ---------------------------------------------------------- */

  const initStatsCounter = () => {
    const section = document.querySelector('.stats-section');
    if (!section) return;

    const numbers = [...section.querySelectorAll('.stat-number')];
    if (numbers.length === 0) return;

    let animated = false; // Only animate once

    /**
     * Animate a single counter from 0 to target.
     * Uses ease-out: fast start, slow end.
     *
     * @param {HTMLElement} el       The .stat-number element
     * @param {number}      target   The target number (from data-target)
     * @param {number}      duration Total animation time in ms
     */
    const animateCounter = (el, target, duration = 2000) => {
      const start = performance.now();
      const suffix = el.dataset.suffix ?? '';   // e.g. "+", "%"
      const prefix = el.dataset.prefix ?? '';   // e.g. "₹"

      const step = (now) => {
        const elapsed = now - start;
        const progress = Math.min(elapsed / duration, 1);

        // Ease-out cubic: 1 - (1 - t)^3 — fast start, decelerating end
        const eased = 1 - (1 - progress) ** 3;
        const value = Math.round(eased * target);

        el.textContent = prefix + value.toLocaleString('en-IN') + suffix;

        if (progress < 1) {
          requestAnimationFrame(step);
        }
      };

      requestAnimationFrame(step);
    };

    // --- IntersectionObserver to trigger animation ---
    const observer = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting && !animated) {
            animated = true;
            numbers.forEach((el) => {
              const target = parseInt(el.dataset.target, 10);
              if (!isNaN(target)) {
                animateCounter(el, target);
              }
            });
            observer.unobserve(section);
          }
        });
      },
      { threshold: 0.3 }
    );

    observer.observe(section);
  };

  /* ----------------------------------------------------------
     5. Course Filter Tabs
     ---------------------------------------------------------- */

  const initCourseFilter = () => {
    const filterBtns = [...document.querySelectorAll('.course-filter-btn')];
    const cards = [...document.querySelectorAll('.course-card')];

    if (filterBtns.length === 0 || cards.length === 0) return;

    /**
     * Show/hide cards based on category and toggle active tab.
     * @param {string} category  The category to filter by ("all" shows everything)
     */
    const filterCards = (category) => {
      // Update active tab
      filterBtns.forEach((btn) => {
        btn.classList.toggle('active', btn.dataset.category === category);
      });

      // Show/hide cards with smooth fade
      cards.forEach((card) => {
        const match = category === 'all' || card.dataset.category === category;
        if (match) {
          card.style.display = '';
          // Trigger reflow before adding opacity for the fade-in
          requestAnimationFrame(() => {
            card.style.opacity = '1';
            card.style.transform = 'translateY(0)';
          });
        } else {
          card.style.opacity = '0';
          card.style.transform = 'translateY(10px)';
          // After transition ends, hide completely
          card.addEventListener('transitionend', function handler() {
            if (card.style.opacity === '0') {
              card.style.display = 'none';
            }
            card.removeEventListener('transitionend', handler);
          });
        }
      });
    };

    // Add transition styles to cards for smooth fade
    cards.forEach((card) => {
      card.style.transition = 'opacity 0.35s ease, transform 0.35s ease';
      card.style.opacity = '1';
    });

    // Attach click handlers
    filterBtns.forEach((btn) => {
      btn.addEventListener('click', () => {
        filterCards(btn.dataset.category ?? 'all');
      });
    });
  };

  /* ----------------------------------------------------------
     6. Scroll Animations
     ---------------------------------------------------------- */

  const initScrollAnimations = () => {
    const elements = [...document.querySelectorAll('.animate-on-scroll')];
    if (elements.length === 0) return;

    const observer = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            const el = entry.target;
            // Stagger delay from data-delay attribute (ms)
            const delay = parseInt(el.dataset.delay ?? '0', 10);
            setTimeout(() => {
              el.classList.add('visible');
            }, delay);
            observer.unobserve(el);
          }
        });
      },
      { threshold: 0.15, rootMargin: '0px 0px -40px 0px' }
    );

    elements.forEach((el) => observer.observe(el));
  };

  /* ----------------------------------------------------------
     7. FAQ Accordion
     ---------------------------------------------------------- */

  const initFaqAccordion = () => {
    const faqItems = [...document.querySelectorAll('.faq-item')];
    if (faqItems.length === 0) return;

    faqItems.forEach((item) => {
      item.addEventListener('toggle', () => {
        if (item.open) {
          // Close all other <details> for clean accordion UX
          faqItems.forEach((other) => {
            if (other !== item && other.open) {
              other.removeAttribute('open');
              other.classList.remove('open');
            }
          });
          item.classList.add('open');
        } else {
          item.classList.remove('open');
        }
      });
    });
  };

  /* ----------------------------------------------------------
     8. Testimonial Carousel
     ---------------------------------------------------------- */

  const initTestimonialCarousel = () => {
    const wrapper = document.querySelector('.testimonials-wrapper');
    if (!wrapper) return;

    const track = wrapper.querySelector('.testimonials-track');
    const cards = [...wrapper.querySelectorAll('.testimonial-card')];
    const prevBtn = wrapper.querySelector('.testimonials-arrow-prev') ??
                    wrapper.querySelectorAll('.testimonials-arrow')[0];
    const nextBtn = wrapper.querySelector('.testimonials-arrow-next') ??
                    wrapper.querySelectorAll('.testimonials-arrow')[1];
    const dotsWrap = wrapper.querySelector('.testimonials-dots');
    const dots = dotsWrap ? [...dotsWrap.querySelectorAll('.testimonials-dot')] : [];

    if (cards.length === 0 || !track) return;

    let currentIndex = 0;
    let autoTimer = null;
    let touchStartX = 0;
    let cardsPerView = 1;

    /** Calculate how many cards to show based on viewport */
    const getCardsPerView = () => (window.matchMedia('(min-width: 768px)').matches ? 3 : 1);

    /** Total "pages" of slides */
    const totalPages = () => Math.ceil(cards.length / cardsPerView);

    /** Get the max valid starting index */
    const maxIndex = () => Math.max(0, cards.length - cardsPerView);

    /** Move the track to the current index */
    const updateTrack = () => {
      const gap = 16; // matches CSS gap
      const cardWidth = cards[0].offsetWidth;
      const offset = currentIndex * (cardWidth + gap);
      track.style.transform = `translateX(-${offset}px)`;

      // Update dot active states
      const page = Math.floor(currentIndex / cardsPerView);
      dots.forEach((dot, i) => {
        dot.classList.toggle('active', i === page);
      });
    };

    /** Set card widths based on cards-per-view */
    const setCardWidths = () => {
      cardsPerView = getCardsPerView();
      const wrapperWidth = wrapper.offsetWidth;
      const gap = 16;
      const cardWidth = (wrapperWidth - gap * (cardsPerView - 1)) / cardsPerView;

      cards.forEach((card) => {
        card.style.minWidth = `${cardWidth}px`;
        card.style.flex = `0 0 ${cardWidth}px`;
      });
    };

    const goNext = () => {
      currentIndex = (currentIndex + cardsPerView) % cards.length;
      // If we'd end up past the end, snap to the last valid index
      if (currentIndex > maxIndex()) currentIndex = 0; // infinite loop
      updateTrack();
    };

    const goPrev = () => {
      currentIndex -= cardsPerView;
      if (currentIndex < 0) currentIndex = maxIndex(); // infinite loop wrap
      updateTrack();
    };

    const goToPage = (page) => {
      currentIndex = page * cardsPerView;
      if (currentIndex > maxIndex()) currentIndex = maxIndex();
      updateTrack();
    };

    /** Start auto-play (4 s interval) */
    const startAuto = () => {
      stopAuto();
      autoTimer = setInterval(goNext, 4000);
    };

    const stopAuto = () => {
      if (autoTimer) {
        clearInterval(autoTimer);
        autoTimer = null;
      }
    };

    // --- Arrow handlers ---
    prevBtn?.addEventListener('click', () => { goPrev(); startAuto(); });
    nextBtn?.addEventListener('click', () => { goNext(); startAuto(); });

    // --- Dot handlers ---
    dots.forEach((dot, i) => {
      dot.addEventListener('click', () => { goToPage(i); startAuto(); });
    });

    // --- Touch swipe ---
    wrapper.addEventListener('touchstart', (e) => {
      touchStartX = e.changedTouches[0].screenX;
      stopAuto();
    }, { passive: true });

    wrapper.addEventListener('touchend', (e) => {
      const diff = e.changedTouches[0].screenX - touchStartX;
      if (Math.abs(diff) > 50) {
        diff > 0 ? goPrev() : goNext();
      }
      startAuto();
    }, { passive: true });

    // --- Pause on hover ---
    wrapper.addEventListener('mouseenter', stopAuto);
    wrapper.addEventListener('mouseleave', startAuto);

    // --- Responsive: recalculate on resize ---
    window.addEventListener('resize', debounce(() => {
      setCardWidths();
      // Clamp currentIndex if cardsPerView changed
      if (currentIndex > maxIndex()) currentIndex = maxIndex();
      updateTrack();
    }, 200));

    // --- Init ---
    setCardWidths();
    updateTrack();
    startAuto();
  };

  /* ----------------------------------------------------------
     9. Branch Horizontal Scroll (Mobile)
     ---------------------------------------------------------- */

  const initBranchScroll = () => {
    const grid = document.querySelector('.branches-grid');
    if (!grid) return;

    let isDragging = false;
    let startX = 0;
    let scrollStart = 0;

    /** Show or hide scroll indicators based on overflow */
    const updateIndicators = () => {
      const hasOverflow = grid.scrollWidth > grid.clientWidth;
      grid.classList.toggle('has-overflow', hasOverflow);

      // Remove any existing indicators
      const section = grid.closest('.branches-section');
      const existingLeft = section?.querySelector('.scroll-indicator-left');
      const existingRight = section?.querySelector('.scroll-indicator-right');
      existingLeft?.remove();
      existingRight?.remove();

      if (!hasOverflow || !section) return;

      // Create scroll indicators
      const wrapper = document.createElement('div');
      wrapper.className = 'scroll-indicators';
      wrapper.style.cssText = 'position:relative;';

      const createIndicator = (side) => {
        const btn = document.createElement('button');
        btn.className = `scroll-indicator-${side}`;
        btn.setAttribute('aria-label', `Scroll ${side}`);
        btn.style.cssText = `
          position: absolute;
          top: 50%;
          ${side}: 0;
          transform: translateY(-50%);
          width: 32px;
          height: 32px;
          border-radius: 50%;
          background: rgba(26, 79, 160, 0.85);
          color: #fff;
          display: flex;
          align-items: center;
          justify-content: center;
          cursor: pointer;
          z-index: 5;
          font-size: 0.75rem;
          border: none;
          box-shadow: 0 2px 8px rgba(0,0,0,0.15);
          transition: opacity 0.25s ease;
        `;
        btn.innerHTML = side === 'left' ? '&#9664;' : '&#9654;';
        return btn;
      };

      const leftBtn = createIndicator('left');
      const rightBtn = createIndicator('right');

      leftBtn.addEventListener('click', () => {
        grid.scrollBy({ left: -260, behavior: 'smooth' });
      });
      rightBtn.addEventListener('click', () => {
        grid.scrollBy({ left: 260, behavior: 'smooth' });
      });

      // Position the section relatively so indicators are absolute inside it
      section.style.position = 'relative';
      section.appendChild(leftBtn);
      section.appendChild(rightBtn);

      // Update indicator visibility on scroll
      const toggleIndicators = () => {
        leftBtn.style.opacity = grid.scrollLeft > 10 ? '1' : '0';
        rightBtn.style.opacity =
          grid.scrollLeft < grid.scrollWidth - grid.clientWidth - 10 ? '1' : '0';
      };

      grid.addEventListener('scroll', throttle(toggleIndicators, 100), { passive: true });
      toggleIndicators();
    };

    // --- Drag-to-scroll (touch + mouse) ---
    grid.addEventListener('mousedown', (e) => {
      isDragging = true;
      startX = e.pageX - grid.offsetLeft;
      scrollStart = grid.scrollLeft;
      grid.style.cursor = 'grabbing';
    });

    grid.addEventListener('mousemove', (e) => {
      if (!isDragging) return;
      e.preventDefault();
      const x = e.pageX - grid.offsetLeft;
      const walk = (x - startX) * 1.5;
      grid.scrollLeft = scrollStart - walk;
    });

    const stopDrag = () => {
      isDragging = false;
      grid.style.cursor = '';
    };

    grid.addEventListener('mouseup', stopDrag);
    grid.addEventListener('mouseleave', stopDrag);

    // --- Init scroll indicators ---
    updateIndicators();
    // Re-check on resize
    window.addEventListener('resize', debounce(updateIndicators, 300));
  };

  /* ----------------------------------------------------------
     10. Toppers Mobile Slider
     ---------------------------------------------------------- */

  const initToppersSlider = () => {
    const grid = document.querySelector('.toppers-grid');
    if (!grid) return;

    let touchStartX = 0;

    // On mobile: enable swipe (CSS already has overflow-x: auto + scroll-snap)
    // On desktop: the grid becomes a 4-column layout (handled by CSS media query)
    // We just add touch swipe support here
    grid.addEventListener('touchstart', (e) => {
      touchStartX = e.changedTouches[0].screenX;
    }, { passive: true });

    grid.addEventListener('touchend', (e) => {
      const diff = e.changedTouches[0].screenX - touchStartX;
      if (Math.abs(diff) > 50) {
        grid.scrollBy({
          left: diff > 0 ? -220 : 220,
          behavior: 'smooth',
        });
      }
    }, { passive: true });
  };

  /* ----------------------------------------------------------
     11. Smooth Scroll
     ---------------------------------------------------------- */

  const initSmoothScroll = () => {
    document.querySelectorAll('a[href^="#"]').forEach((anchor) => {
      anchor.addEventListener('click', (e) => {
        const targetId = anchor.getAttribute('href');
        if (!targetId || targetId === '#') return;

        const target = document.querySelector(targetId);
        if (!target) return;

        e.preventDefault();

        // Account for sticky header height
        const header = document.querySelector('.main-nav');
        const headerHeight = header ? header.offsetHeight : 0;
        const targetTop = target.getBoundingClientRect().top + window.scrollY - headerHeight - 16;

        window.scrollTo({
          top: targetTop,
          behavior: 'smooth',
        });
      });
    });
  };

  /* ----------------------------------------------------------
     12. Back to Top Button
     ---------------------------------------------------------- */

  const initBackToTop = () => {
    // Create the button element if it doesn't exist in the HTML
    let btn = document.querySelector('.back-to-top');
    if (!btn) {
      btn = document.createElement('button');
      btn.className = 'back-to-top';
      btn.setAttribute('aria-label', 'Back to top');
      btn.innerHTML = '&#9650;'; // Up-pointing triangle
      btn.style.cssText = `
        position: fixed;
        bottom: 30px;
        right: 30px;
        width: 44px;
        height: 44px;
        border-radius: 50%;
        background-color: #1a4fa0;
        color: #ffffff;
        border: none;
        font-size: 1rem;
        cursor: pointer;
        z-index: 999;
        display: flex;
        align-items: center;
        justify-content: center;
        opacity: 0;
        visibility: hidden;
        transform: translateY(10px);
        transition: opacity 0.3s ease, visibility 0.3s ease, transform 0.3s ease, background-color 0.25s ease;
        box-shadow: 0 4px 14px rgba(26, 79, 160, 0.35);
      `;
      document.body.appendChild(btn);
    }

    const onScroll = () => {
      requestAnimationFrame(() => {
        if (window.scrollY > 300) {
          btn.style.opacity = '1';
          btn.style.visibility = 'visible';
          btn.style.transform = 'translateY(0)';
        } else {
          btn.style.opacity = '0';
          btn.style.visibility = 'hidden';
          btn.style.transform = 'translateY(10px)';
        }
      });
    };

    window.addEventListener('scroll', throttle(onScroll, 150), { passive: true });

    btn.addEventListener('click', () => {
      window.scrollTo({ top: 0, behavior: 'smooth' });
    });

    btn.addEventListener('mouseenter', () => {
      btn.style.backgroundColor = '#0d2b6e';
    });
    btn.addEventListener('mouseleave', () => {
      btn.style.backgroundColor = '#1a4fa0';
    });
  };

  /* ----------------------------------------------------------
     13. Image Lazy Loading
     ---------------------------------------------------------- */

  const initLazyLoading = () => {
    const images = [...document.querySelectorAll('img[data-src]')];
    if (images.length === 0) return;

    // Add base transition for fade-in
    const style = document.createElement('style');
    style.textContent = `
      img[data-src] {
        opacity: 0;
        transition: opacity 0.4s ease;
      }
      img.fade-in {
        opacity: 1;
      }
    `;
    document.head.appendChild(style);

    const observer = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            const img = entry.target;
            const src = img.dataset.src;
            if (src) {
              img.src = src;
              img.removeAttribute('data-src');
              img.addEventListener('load', () => {
                img.classList.add('fade-in');
              }, { once: true });
              // Fallback: if image is already cached / loaded
              if (img.complete) {
                img.classList.add('fade-in');
              }
            }
            observer.unobserve(img);
          }
        });
      },
      { rootMargin: '100px 0px' } // Start loading 100 px before visible
    );

    images.forEach((img) => observer.observe(img));
  };

  /* ----------------------------------------------------------
     14. Gallery Lightbox
     ---------------------------------------------------------- */

  const initGalleryLightbox = () => {
    const lightbox = document.getElementById('galleryLightbox');
    if (!lightbox) return;

    const lightboxImg = document.getElementById('lightboxImg');
    const lightboxCaption = document.getElementById('lightboxCaption');
    const closeBtn = lightbox.querySelector('.gallery-lightbox-close');

    // Make openLightbox globally available (called from onclick in HTML)
    window.openLightbox = (card) => {
      const img = card.querySelector('img');
      if (!img || !lightboxImg) return;

      lightboxImg.src = img.src;
      lightboxImg.alt = img.alt;
      if (lightboxCaption) {
        lightboxCaption.textContent = img.dataset.title || img.alt || '';
      }
      lightbox.classList.add('active');
      document.body.style.overflow = 'hidden';
    };

    const closeLightbox = () => {
      lightbox.classList.remove('active');
      document.body.style.overflow = '';
    };

    closeBtn?.addEventListener('click', closeLightbox);

    lightbox.addEventListener('click', (e) => {
      if (e.target === lightbox) closeLightbox();
    });

    document.addEventListener('keydown', (e) => {
      if (e.key === 'Escape' && lightbox.classList.contains('active')) {
        closeLightbox();
      }
    });
  };

  /* ----------------------------------------------------------
     15. Offer Popup
     ---------------------------------------------------------- */

  const initOfferPopup = () => {
    const overlay = document.getElementById('offerPopupOverlay');
    if (!overlay) return;

    const closeBtn = document.getElementById('offerPopupClose');

    // Check if popup was already dismissed in this session
    const popupDismissed = sessionStorage.getItem('gmind_offer_dismissed');
    if (popupDismissed === '1') return;

    // Show popup after a short delay (2 seconds)
    const showTimer = setTimeout(() => {
      overlay.classList.add('active');
      document.body.style.overflow = 'hidden';
    }, 2000);

    const closePopup = () => {
      overlay.classList.remove('active');
      document.body.style.overflow = '';
      sessionStorage.setItem('gmind_offer_dismissed', '1');
    };

    closeBtn?.addEventListener('click', closePopup);

    // Close on overlay click
    overlay.addEventListener('click', (e) => {
      if (e.target === overlay) closePopup();
    });

    // Close on Escape key
    document.addEventListener('keydown', (e) => {
      if (e.key === 'Escape' && overlay.classList.contains('active')) {
        closePopup();
      }
    });
  };

  /* ----------------------------------------------------------
     Initialise Everything on DOMContentLoaded
     ---------------------------------------------------------- */

  const init = () => {
    initHeroSlider();
    initStickyHeader();
    initMobileMenu();
    initStatsCounter();
    initCourseFilter();
    initScrollAnimations();
    initFaqAccordion();
    initTestimonialCarousel();
    initBranchScroll();
    initToppersSlider();
    initSmoothScroll();
    initBackToTop();
    initLazyLoading();
    initGalleryLightbox();
    initOfferPopup();
  };

  // Fire when DOM is ready
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init);
  } else {
    // DOM already parsed (script loaded with defer or at bottom)
    init();
  }

})();
