/**
 * Blokio global.js
 * Vanilla ES6+, no dependencies. Everything here is progressive
 * enhancement — the theme is fully usable with JS disabled.
 */
(function () {
  'use strict';

  var reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  /* Sticky header shadow-on-scroll */
  var header = document.querySelector('.blokio-header');
  if (header) {
    var onScroll = function () {
      header.classList.toggle('is-scrolled', window.scrollY > 8);
    };
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
  }

  /* Back to top */
  var backToTop = document.querySelector('.blokio-back-to-top');
  if (backToTop) {
    window.addEventListener(
      'scroll',
      function () {
        backToTop.classList.toggle('is-visible', window.scrollY > 600);
      },
      { passive: true }
    );

    backToTop.addEventListener('click', function () {
      window.scrollTo({ top: 0, behavior: reduceMotion ? 'auto' : 'smooth' });
    });
  }

  /* Search popup */
  var searchToggle = document.querySelector('.blokio-search-toggle');
  var searchPopup = document.querySelector('.blokio-search-popup');
  var previousFocus = null;

  if (searchToggle && searchPopup) {
    var getFocusableElements = function () {
      return Array.prototype.slice.call(
        searchPopup.querySelectorAll(
          'a[href], button:not([disabled]), input:not([disabled]), ' +
            'select:not([disabled]), textarea:not([disabled]), ' +
            '[tabindex]:not([tabindex="-1"])'
        )
      ).filter(function (element) {
        return element.offsetWidth || element.offsetHeight || element.getClientRects().length;
      });
    };

    var closePopup = function () {
      searchPopup.classList.remove('is-open');
      searchToggle.setAttribute('aria-expanded', 'false');

      if (previousFocus && document.contains(previousFocus)) {
        previousFocus.focus();
      } else {
        searchToggle.focus();
      }

      previousFocus = null;
    };

    var trapFocus = function (event) {
      if (event.key !== 'Tab' || !searchPopup.classList.contains('is-open')) {
        return;
      }

      var focusableElements = getFocusableElements();

      if (!focusableElements.length) {
        event.preventDefault();
        return;
      }

      var firstElement = focusableElements[0];
      var lastElement = focusableElements[focusableElements.length - 1];

      if (!searchPopup.contains(document.activeElement)) {
        event.preventDefault();
        firstElement.focus();
        return;
      }

      if (event.shiftKey && document.activeElement === firstElement) {
        event.preventDefault();
        lastElement.focus();
      } else if (!event.shiftKey && document.activeElement === lastElement) {
        event.preventDefault();
        firstElement.focus();
      }
    };

    searchToggle.addEventListener('click', function () {
      var isOpen = searchPopup.classList.toggle('is-open');
      searchToggle.setAttribute('aria-expanded', String(isOpen));

      if (isOpen) {
        previousFocus = document.activeElement;

        var input = searchPopup.querySelector('input[type="search"]');
        if (input) {
          input.focus();
        } else {
          var focusableElements = getFocusableElements();
          if (focusableElements.length) {
            focusableElements[0].focus();
          }
        }
      } else {
        closePopup();
      }
    });

    searchPopup.addEventListener('click', function (event) {
      if (event.target === searchPopup) {
        closePopup();
      }
    });

    var closeButton = searchPopup.querySelector('.blokio-search-popup__close');
    if (closeButton) {
      closeButton.addEventListener('click', closePopup);
    }

    document.addEventListener('keydown', function (event) {
      if (!searchPopup.classList.contains('is-open')) {
        return;
      }

      if (event.key === 'Escape') {
        event.preventDefault();
        closePopup();
        return;
      }

      trapFocus(event);
    });
  }

  /* Dark / light mode toggle. The initial theme (based on a saved
     preference, falling back to the system setting) is already
     applied before paint by the inline script in wp_head — this
     just wires up the button to flip it and remember the choice. */
  var THEME_STORAGE_KEY = 'blokio-theme';
  var themeToggles = document.querySelectorAll('.blokio-theme-toggle');

  function blokioStoredTheme() {
    try {
      return window.localStorage.getItem(THEME_STORAGE_KEY);
    } catch (e) {
      return null;
    }
  }

  function blokioIsDark() {
    var stored = blokioStoredTheme();
    if (stored === 'dark') {
      return true;
    }
    if (stored === 'light') {
      return false;
    }
    return window.matchMedia('(prefers-color-scheme: dark)').matches;
  }

  function blokioUpdateToggles() {
    var dark = blokioIsDark();
    themeToggles.forEach(function (btn) {
      btn.setAttribute('aria-pressed', String(dark));
    });
  }

  if (themeToggles.length) {
    blokioUpdateToggles();

    themeToggles.forEach(function (btn) {
      btn.addEventListener('click', function () {
        var next = blokioIsDark() ? 'light' : 'dark';
        document.documentElement.setAttribute('data-blokio-theme', next);

        try {
          window.localStorage.setItem(THEME_STORAGE_KEY, next);
        } catch (e) {
          /* Storage unavailable (private mode, etc.) — theme still
             flips for this page view via the attribute above. */
        }

        blokioUpdateToggles();
      });
    });
  }

  /* Scroll-reveal for elements marked .blokio-reveal, respects
     prefers-reduced-motion by doing nothing (CSS already shows them). */
  if (!reduceMotion && 'IntersectionObserver' in window) {
    var revealTargets = document.querySelectorAll('.blokio-reveal');

    if (revealTargets.length) {
      var observer = new IntersectionObserver(
        function (entries) {
          entries.forEach(function (entry) {
            if (entry.isIntersecting) {
              entry.target.classList.add('is-visible');
              observer.unobserve(entry.target);
            }
          });
        },
        { threshold: 0.15 }
      );

      revealTargets.forEach(function (el) {
        observer.observe(el);
      });
    }
  } else {
    document.querySelectorAll('.blokio-reveal').forEach(function (el) {
      el.classList.add('is-visible');
    });
  }
})();
