// Dark mode functionality
(function() {
  // Check for saved theme preference or default to light mode
  const currentTheme = localStorage.getItem('theme') || 'light';
  document.documentElement.setAttribute('data-theme', currentTheme);
})();

function toggleDarkMode() {
  const currentTheme = document.documentElement.getAttribute('data-theme');
  const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
  document.documentElement.setAttribute('data-theme', newTheme);
  localStorage.setItem('theme', newTheme);
}

// Font size functionality
(function() {
  const sizes = ['small', 'normal', 'large', 'x-large'];
  const savedSize = localStorage.getItem('fontSize') || 'normal';
  if (savedSize !== 'normal') {
    document.documentElement.setAttribute('data-font-size', savedSize);
  }
})();

function toggleFontSize() {
  const currentSize = document.documentElement.getAttribute('data-font-size');
  if (currentSize === 'large') {
    document.documentElement.removeAttribute('data-font-size');
    localStorage.removeItem('fontSize');
  } else {
    document.documentElement.setAttribute('data-font-size', 'large');
    localStorage.setItem('fontSize', 'large');
  }
}

// Bookmark functionality
function getBookmarks() {
  try {
    return JSON.parse(localStorage.getItem('kjvBookmarks') || '[]');
  } catch (e) {
    return [];
  }
}

function saveBookmarks(bookmarks) {
  localStorage.setItem('kjvBookmarks', JSON.stringify(bookmarks));
}

function isBookmarked(url) {
  var bookmarks = getBookmarks();
  return bookmarks.some(function(b) { return b.url === url; });
}

function getPageExcerpt() {
  var article = document.querySelector('article');
  if (!article) return '';

  var clone = article.cloneNode(true);
  clone.querySelectorAll('.breadcrumb, .breadcrumb-actions, .sidenote, .marginnote, .toc, script, style, nav, button, h1, h2, h3').forEach(function(el) {
    el.remove();
  });

  var text = (clone.textContent || clone.innerText || '').trim();
  // Get first meaningful chunk
  text = text.replace(/\s+/g, ' ').substring(0, 300);
  return text;
}

function getPageDescription() {
  var meta = document.querySelector('meta[name="description"]');
  return meta ? meta.getAttribute('content') : '';
}

function getPageBreadcrumbs() {
  var breadcrumb = document.querySelector('.breadcrumb');
  if (!breadcrumb) return [];

  var crumbs = [];
  breadcrumb.querySelectorAll('a, span:not(.breadcrumb-separator):not(.breadcrumb-actions)').forEach(function(el) {
    if (el.classList.contains('breadcrumb-actions')) return;
    if (el.closest('.breadcrumb-actions')) return;
    var text = el.textContent.trim();
    if (text && text !== '>' && text.length > 0) {
      crumbs.push({
        text: text,
        url: el.tagName === 'A' ? el.getAttribute('href') : null
      });
    }
  });
  // Drop the last item (it's the current page title)
  if (crumbs.length > 0) {
    crumbs.pop();
  }
  return crumbs;
}

function toggleBookmark() {
  var btn = document.getElementById('bookmark-btn');
  var url = window.location.pathname;
  var title = document.title.replace(' - KJV Study', '').replace(' - KJV Bible', '');
  var bookmarks = getBookmarks();

  var existingIndex = bookmarks.findIndex(function(b) { return b.url === url; });

  if (existingIndex >= 0) {
    // Remove bookmark
    bookmarks.splice(existingIndex, 1);
    if (btn) btn.classList.remove('bookmarked');
    showBookmarkToast(false);
  } else {
    // Add bookmark with description, breadcrumbs, and excerpt
    bookmarks.unshift({
      url: url,
      title: title,
      description: getPageDescription(),
      breadcrumbs: getPageBreadcrumbs(),
      excerpt: getPageExcerpt(),
      date: new Date().toISOString()
    });
    if (btn) btn.classList.add('bookmarked');
    showBookmarkToast(true);
  }

  saveBookmarks(bookmarks);
  updateStarsBadge();
}

function showBookmarkToast(added) {
  var toast = document.getElementById('bookmark-toast');
  if (!toast) return;

  if (added) {
    toast.innerHTML = 'Added to <a href="/stars">Starred Pages</a>';
  } else {
    toast.innerHTML = 'Removed from Starred Pages';
  }

  toast.classList.add('show');

  // Hide after 3 seconds
  setTimeout(function() {
    toast.classList.remove('show');
  }, 3000);
}

// Check bookmark state on page load and update nav badges
(function() {
  document.addEventListener('DOMContentLoaded', function() {
    var btn = document.getElementById('bookmark-btn');
    if (btn && isBookmarked(window.location.pathname)) {
      btn.classList.add('bookmarked');
    }

    // Update nav badges
    updateStarsBadge();
    updateReadingPlansBadge();
  });
})();

function updateStarsBadge() {
  var badge = document.getElementById('stars-badge');
  if (!badge) return;

  var bookmarks = getBookmarks();
  badge.textContent = bookmarks.length > 0 ? bookmarks.length : '';
}

// Reading plans progress badge
function updateReadingPlansBadge() {
  var badge = document.getElementById('reading-plans-badge');
  if (!badge) return;

  // Reading plan IDs and their total days
  var planDays = {
    'chronological': 365,
    'one-year': 365,
    'new-testament': 90,
    'gospels-acts': 30,
    'psalms-proverbs': 31,
    'pentateuch': 40,
    'prophets': 60,
    'paul-epistles': 30,
    'minor-prophets': 14,
    'wisdom': 30,
    'historical': 45,
    'general-epistles': 14
  };

  var totalCompleted = 0;
  var totalDays = 0;
  var activePlans = 0;

  // Check each plan
  for (var planId in planDays) {
    var storageKey = 'reading-plan-' + planId;
    var saved = localStorage.getItem(storageKey);
    if (saved) {
      try {
        var data = JSON.parse(saved);
        if (data.completed && data.completed.length > 0) {
          activePlans++;
          totalCompleted += data.completed.length;
          totalDays += planDays[planId];
        }
      } catch (e) {
        // Invalid JSON, skip
      }
    }
  }

  if (activePlans === 0 || totalDays === 0) {
    badge.textContent = '';
    return;
  }

  var percent = Math.round((totalCompleted / totalDays) * 100);
  badge.textContent = percent + '%';
}

// Page speech toggle (for breadcrumb button) - triggers spacebar speech
function togglePageSpeech() {
  // Clear suppressSpace flag since this is a button click, not a keyboard repeat
  if (window.KJVResourceSpeech) {
    window.KJVResourceSpeech.suppressSpace = false;
  }

  // Simulate spacebar press to use existing speech system
  var event = new KeyboardEvent('keydown', { key: ' ', code: 'Space', bubbles: true });
  document.dispatchEvent(event);

  // Update button state after a tick
  setTimeout(updateSpeechButtonState, 50);
}

function updateSpeechButtonState() {
  var btn = document.getElementById('speech-toggle-btn');
  if (!btn) return;

  var isSpeaking = (window.KJVResourceSpeech && window.KJVResourceSpeech.speaking) ||
                   (window.KJVSpeech && window.KJVSpeech.speaking) ||
                   ('speechSynthesis' in window && (speechSynthesis.speaking || speechSynthesis.pending));

  if (isSpeaking) {
    btn.classList.add('speaking');
  } else {
    btn.classList.remove('speaking');
  }
}

// Poll for speech state changes to keep button in sync
setInterval(updateSpeechButtonState, 500);

// Red letter toggle functionality
(function() {
  // Check for saved red letter preference or default to enabled
  const redLettersEnabled = localStorage.getItem('redLetters') !== 'disabled';
  if (!redLettersEnabled) {
    document.documentElement.setAttribute('data-red-letters', 'disabled');
  }
})();

function toggleRedLetters() {
  const currentState = document.documentElement.getAttribute('data-red-letters');
  const newState = currentState === 'disabled' ? 'enabled' : 'disabled';

  if (newState === 'disabled') {
    document.documentElement.setAttribute('data-red-letters', 'disabled');
    localStorage.setItem('redLetters', 'disabled');
  } else {
    document.documentElement.removeAttribute('data-red-letters');
    localStorage.removeItem('redLetters');
  }
}

// Sticky breadcrumb detection
(function() {
  var breadcrumb = document.getElementById('breadcrumb');
  if (!breadcrumb) return;

  var ticking = false;

  function updateStickyState() {
    // Check if breadcrumb is at the top (stuck)
    var rect = breadcrumb.getBoundingClientRect();
    if (rect.top <= 0) {
      breadcrumb.classList.add('stuck');
    } else {
      breadcrumb.classList.remove('stuck');
    }
    ticking = false;
  }

  window.addEventListener('scroll', function() {
    if (!ticking) {
      window.requestAnimationFrame(updateStickyState);
      ticking = true;
    }
  }, { passive: true });
})();

// Sidebar collapse state persistence (mobile only)
(function() {
  var toggle = document.getElementById('sidebar-toggle');
  if (!toggle) return;

  // On mobile, default to collapsed (don't restore from localStorage - always start closed)
  var isMobile = window.innerWidth <= 1200;
  if (isMobile) {
    toggle.checked = false;

    // Close sidebar when clicking any link inside it (for mobile navigation)
    var sidebar = document.querySelector('.nav-sidebar');
    if (sidebar) {
      sidebar.addEventListener('click', function(e) {
        var link = e.target.closest('a');
        if (link && link.href) {
          // Close sidebar on navigation
          toggle.checked = false;
        }
      });
    }
  }
})();

// Details elements (subsections) collapse state persistence
(function() {
  // Get all details elements in sidebar
  var detailsElements = document.querySelectorAll('.nav-sidebar details');

  // Restore saved states
  detailsElements.forEach(function(details) {
    var id = details.id || details.querySelector('summary')?.textContent.trim();
    if (id) {
      var savedState = localStorage.getItem('sidebar-details-' + id);
      if (savedState === 'open') {
        details.open = true;
      } else if (savedState === 'closed') {
        details.open = false;
      }
    }
  });

  // Save state on toggle
  detailsElements.forEach(function(details) {
    details.addEventListener('toggle', function() {
      var id = this.id || this.querySelector('summary')?.textContent.trim();
      if (id) {
        localStorage.setItem('sidebar-details-' + id, this.open ? 'open' : 'closed');
      }
    });
  });
})();

// Universal search functionality with smart verse navigation
(function() {
  var searchInput = document.getElementById('sidebar-search-input');
  var dropdown = document.getElementById('search-results-dropdown');
  if (!searchInput || !dropdown) return;

  var searchTimeout = null;
  var selectedIndex = -1;
  var currentResults = [];

  // Book name mapping (same as homepage)
  var bookMap = {
    'genesis': 'Genesis', 'exodus': 'Exodus', 'leviticus': 'Leviticus', 'numbers': 'Numbers',
    'deuteronomy': 'Deuteronomy', 'joshua': 'Joshua', 'judges': 'Judges', 'ruth': 'Ruth',
    '1 samuel': '1 Samuel', '2 samuel': '2 Samuel', '1 kings': '1 Kings', '2 kings': '2 Kings',
    '1 chronicles': '1 Chronicles', '2 chronicles': '2 Chronicles', 'ezra': 'Ezra', 'nehemiah': 'Nehemiah',
    'esther': 'Esther', 'job': 'Job', 'psalms': 'Psalms', 'psalm': 'Psalms', 'proverbs': 'Proverbs',
    'ecclesiastes': 'Ecclesiastes', 'song of solomon': 'Song of Solomon', 'isaiah': 'Isaiah',
    'jeremiah': 'Jeremiah', 'lamentations': 'Lamentations', 'ezekiel': 'Ezekiel', 'daniel': 'Daniel',
    'hosea': 'Hosea', 'joel': 'Joel', 'amos': 'Amos', 'obadiah': 'Obadiah', 'jonah': 'Jonah',
    'micah': 'Micah', 'nahum': 'Nahum', 'habakkuk': 'Habakkuk', 'zephaniah': 'Zephaniah',
    'haggai': 'Haggai', 'zechariah': 'Zechariah', 'malachi': 'Malachi', 'matthew': 'Matthew',
    'mark': 'Mark', 'luke': 'Luke', 'john': 'John', 'acts': 'Acts', 'romans': 'Romans',
    '1 corinthians': '1 Corinthians', '2 corinthians': '2 Corinthians', 'galatians': 'Galatians',
    'ephesians': 'Ephesians', 'philippians': 'Philippians', 'colossians': 'Colossians',
    '1 thessalonians': '1 Thessalonians', '2 thessalonians': '2 Thessalonians',
    '1 timothy': '1 Timothy', '2 timothy': '2 Timothy', 'titus': 'Titus', 'philemon': 'Philemon',
    'hebrews': 'Hebrews', 'james': 'James', '1 peter': '1 Peter', '2 peter': '2 Peter',
    '1 john': '1 John', '2 john': '2 John', '3 john': '3 John', 'jude': 'Jude', 'revelation': 'Revelation',
    'gen': 'Genesis', 'ex': 'Exodus', 'lev': 'Leviticus', 'num': 'Numbers', 'deut': 'Deuteronomy',
    'josh': 'Joshua', 'judg': 'Judges', 'ru': 'Ruth', '1sam': '1 Samuel', '2sam': '2 Samuel',
    '1ki': '1 Kings', '2ki': '2 Kings', '1chr': '1 Chronicles', '2chr': '2 Chronicles',
    'neh': 'Nehemiah', 'est': 'Esther', 'ps': 'Psalms', 'prov': 'Proverbs', 'eccl': 'Ecclesiastes',
    'isa': 'Isaiah', 'jer': 'Jeremiah', 'lam': 'Lamentations', 'ezek': 'Ezekiel', 'dan': 'Daniel',
    'hos': 'Hosea', 'mic': 'Micah', 'hab': 'Habakkuk', 'zech': 'Zechariah', 'mal': 'Malachi',
    'matt': 'Matthew', 'mk': 'Mark', 'lk': 'Luke', 'jn': 'John', 'rom': 'Romans',
    '1cor': '1 Corinthians', '2cor': '2 Corinthians', 'gal': 'Galatians', 'eph': 'Ephesians',
    'phil': 'Philippians', 'col': 'Colossians', '1thess': '1 Thessalonians', '2thess': '2 Thessalonians',
    '1tim': '1 Timothy', '2tim': '2 Timothy', 'tit': 'Titus', 'heb': 'Hebrews', 'jas': 'James',
    '1pet': '1 Peter', '2pet': '2 Peter', '1jn': '1 John', '2jn': '2 John', '3jn': '3 John', 'rev': 'Revelation'
  };

  function capitalizeBook(name) {
    return bookMap[name.toLowerCase()] || name;
  }

  // Try to parse as Strong's number and return URL, or null
  function parseStrongsNumber(input) {
    // Strong's number format: H1234, G5678, h1234, g5678
    var match = input.match(/^([HhGg])(\d+)$/);
    if (match) {
      var prefix = match[1].toUpperCase();
      var number = match[2];
      return '/strongs/' + prefix + number;
    }
    return null;
  }

  // Try to parse as verse reference and return URL, or null
  function parseVerseReference(input) {
    // Book Chapter:Verse (e.g., "John 3:16")
    var match = input.match(/^(.+)\s+(\d+):(\d+)$/i);
    if (match) {
      var book = capitalizeBook(match[1].trim());
      return '/book/' + encodeURIComponent(book) + '/chapter/' + match[2] + '/verse/' + match[3];
    }
    // Book Chapter Verse (e.g., "Rev 22 20" or "John 3 16")
    match = input.match(/^(.+)\s+(\d+)\s+(\d+)$/i);
    if (match) {
      var book = capitalizeBook(match[1].trim());
      return '/book/' + encodeURIComponent(book) + '/chapter/' + match[2] + '/verse/' + match[3];
    }
    // Book Chapter (e.g., "Genesis 1")
    match = input.match(/^(.+)\s+(\d+)$/i);
    if (match) {
      var book = capitalizeBook(match[1].trim());
      return '/book/' + encodeURIComponent(book) + '/chapter/' + match[2];
    }
    return null;
  }

  // Category labels
  var categoryLabels = {
    books: 'Books',
    verses: 'Verses',
    topics: 'Topics',
    resources: 'Resources',
    stories: 'Stories',
    plans: 'Reading Plans'
  };

  // Render search results
  function renderResults(data) {
    var results = data.results;
    var html = '';
    currentResults = [];

    // Check if query looks like a Strong's number
    var strongsUrl = parseStrongsNumber(data.query.trim());
    if (strongsUrl) {
      html += '<div class="search-results-category">';
      html += '<div class="search-results-category-title">Go to</div>';
      currentResults.push(strongsUrl);
      html += '<a href="' + strongsUrl + '" class="search-result-item selected">';
      html += '<span class="result-title">' + data.query.trim().toUpperCase() + '</span>';
      html += '<span class="result-meta">Strong\'s Concordance</span>';
      html += '</a></div>';
      selectedIndex = 0;
    }

    // Check if query looks like a verse reference
    var verseUrl = parseVerseReference(data.query);
    if (verseUrl && !strongsUrl) {
      html += '<div class="search-results-category">';
      html += '<div class="search-results-category-title">Go to</div>';
      currentResults.push(verseUrl);
      html += '<a href="' + verseUrl + '" class="search-result-item selected">';
      html += '<span class="result-title">' + data.query + '</span>';
      html += '<span class="result-meta">Press Enter to navigate</span>';
      html += '</a></div>';
      selectedIndex = 0;
    }

    if (Object.keys(results).length === 0 && !verseUrl && !strongsUrl) {
      html = '<div class="search-no-results">No results found</div>';
    } else {
      // Render categories in specific order: books, topics, resources, stories, plans, verses
      var categoryOrder = ['books', 'topics', 'resources', 'stories', 'plans', 'verses'];
      categoryOrder.forEach(function(category) {
        if (results[category] && results[category].length > 0) {
          html += '<div class="search-results-category">';
          html += '<div class="search-results-category-title">' + (categoryLabels[category] || category) + '</div>';

          results[category].forEach(function(item) {
            var title = item.name || item.title || item.reference;
            var meta = '';
            if (item.text) meta = item.text;
            else if (item.category) meta = item.category;

            currentResults.push(item.url);
            html += '<a href="' + item.url + '" class="search-result-item">';
            html += '<span class="result-title">' + title + '</span>';
            if (meta) html += '<span class="result-meta">' + meta + '</span>';
            html += '</a>';
          });

          html += '</div>';
        }
      });

      // Add "View all results" link
      html += '<a href="/search?q=' + encodeURIComponent(data.query) + '" class="search-view-all">View all verse results →</a>';
    }

    dropdown.innerHTML = html;
    dropdown.classList.add('show');
    if (!verseUrl) selectedIndex = -1;
  }

  // Perform search
  function doSearch(query) {
    if (query.length < 2) {
      dropdown.classList.remove('show');
      return;
    }

    dropdown.innerHTML = '<div class="search-loading">Searching...</div>';
    dropdown.classList.add('show');

    fetch('/api/universal-search?q=' + encodeURIComponent(query) + '&limit=4')
      .then(function(r) { return r.json(); })
      .then(renderResults)
      .catch(function() {
        dropdown.innerHTML = '<div class="search-no-results">Search error</div>';
      });
  }

  // Input handler with debounce
  searchInput.addEventListener('input', function() {
    var query = this.value.trim();
    clearTimeout(searchTimeout);

    if (query.length < 2) {
      dropdown.classList.remove('show');
      return;
    }

    searchTimeout = setTimeout(function() {
      doSearch(query);
    }, 150);
  });

  // Keyboard navigation
  searchInput.addEventListener('keydown', function(e) {
    var items = dropdown.querySelectorAll('.search-result-item');

    if (e.key === 'ArrowDown') {
      e.preventDefault();
      selectedIndex = Math.min(selectedIndex + 1, items.length - 1);
      updateSelection(items);
    } else if (e.key === 'ArrowUp') {
      e.preventDefault();
      selectedIndex = Math.max(selectedIndex - 1, -1);
      updateSelection(items);
    } else if (e.key === 'Enter') {
      e.preventDefault();
      if (selectedIndex >= 0 && currentResults[selectedIndex]) {
        window.location.href = currentResults[selectedIndex];
      } else {
        // Try Strong's number first, then verse reference, then search
        var strongsUrl = parseStrongsNumber(this.value.trim());
        if (strongsUrl) {
          window.location.href = strongsUrl;
        } else {
          var verseUrl = parseVerseReference(this.value.trim());
          if (verseUrl) {
            window.location.href = verseUrl;
          } else if (this.value.trim()) {
            window.location.href = '/search?q=' + encodeURIComponent(this.value.trim());
          }
        }
      }
    } else if (e.key === 'Escape') {
      dropdown.classList.remove('show');
      this.blur();
    }
  });

  function updateSelection(items) {
    items.forEach(function(item, i) {
      item.classList.toggle('selected', i === selectedIndex);
    });
  }

  // Close dropdown when clicking outside
  document.addEventListener('click', function(e) {
    if (!e.target.closest('.sidebar-search')) {
      dropdown.classList.remove('show');
    }
  });

  // Reopen on focus if there's a query
  searchInput.addEventListener('focus', function() {
    if (this.value.trim().length >= 2) {
      doSearch(this.value.trim());
    }
  });
})();

// Global viewport helpers for keyboard navigation
window.KJVNav = {
  isInViewport: function(el) {
    if (!el) return false;
    var rect = el.getBoundingClientRect();
    return rect.top < window.innerHeight && rect.bottom > 0;
  },
  findFirstVisibleIndex: function(elements) {
    for (var i = 0; i < elements.length; i++) {
      if (this.isInViewport(elements[i])) return i;
    }
    return 0;
  },
  isSelectionOffScreen: function(elements, selectedIndex) {
    if (selectedIndex < 0) return true;
    if (selectedIndex >= elements.length) return true;
    return !this.isInViewport(elements[selectedIndex]);
  },
  // Sidebar navigation state
  sidebarActive: false,
  sidebarIndex: -1,
  sidebarLinks: [],
  currentPageNav: null,

  // Activate sidebar navigation with 'n' key
  initSidebarNav: function() {
    var self = this;
    var sidebar = document.querySelector('.nav-sidebar');
    if (!sidebar) return;

    // Get all navigable links in sidebar
    self.sidebarLinks = Array.from(sidebar.querySelectorAll('a'));

    function clearSidebarSelection() {
      self.sidebarLinks.forEach(function(link) {
        link.style.outline = '';
        link.style.background = '';
      });
    }

    function selectSidebarLink(index) {
      clearSidebarSelection();
      if (self.sidebarLinks.length === 0) return;
      self.sidebarIndex = Math.max(0, Math.min(index, self.sidebarLinks.length - 1));
      var link = self.sidebarLinks[self.sidebarIndex];
      link.style.outline = '2px solid #4a7c59';
      link.style.background = 'rgba(74, 124, 89, 0.1)';
      link.scrollIntoView({ behavior: 'auto', block: 'center' });

      // Expand parent details if collapsed
      var details = link.closest('details');
      if (details && !details.open) {
        details.open = true;
      }
    }

    function exitSidebar() {
      clearSidebarSelection();
      self.sidebarActive = false;
      self.sidebarIndex = -1;
      // Close sidebar on mobile when exiting nav mode
      var sidebarToggle = document.getElementById('sidebar-toggle');
      if (sidebarToggle && sidebarToggle.checked) {
        sidebarToggle.checked = false;
      }
      // Clear page nav selection if exists
      if (self.currentPageNav && self.currentPageNav.clearSelection) {
        self.currentPageNav.clearSelection();
      }
    }

    document.addEventListener('keydown', function(e) {
      if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;

      // 'n' to enter sidebar nav mode
      if (e.key === 'n' && !self.sidebarActive) {
        e.preventDefault();
        // Open sidebar if it's not visible (mobile/collapsed state)
        var sidebarToggle = document.getElementById('sidebar-toggle');
        if (sidebarToggle && !sidebarToggle.checked) {
          sidebarToggle.checked = true;
        }
        self.sidebarActive = true;
        // Clear any page content selection
        if (self.currentPageNav && self.currentPageNav.clearSelection) {
          self.currentPageNav.clearSelection();
        }
        // Start at first link or current page link
        var currentLink = sidebar.querySelector('a.current');
        var startIndex = currentLink ? self.sidebarLinks.indexOf(currentLink) : 0;
        selectSidebarLink(startIndex >= 0 ? startIndex : 0);
        return;
      }

      // Handle sidebar navigation when active
      if (self.sidebarActive) {
        if (e.key === 'ArrowDown' || e.key === 'j') {
          e.preventDefault();
          e.stopPropagation();
          selectSidebarLink(self.sidebarIndex + 1);
          return;
        } else if (e.key === 'ArrowUp' || e.key === 'k') {
          e.preventDefault();
          e.stopPropagation();
          selectSidebarLink(self.sidebarIndex - 1);
          return;
        } else if (e.key === 'Enter') {
          e.preventDefault();
          e.stopPropagation();
          if (self.sidebarIndex >= 0 && self.sidebarLinks[self.sidebarIndex]) {
            window.location.href = self.sidebarLinks[self.sidebarIndex].href;
          }
          return;
        } else if (e.key === 'Escape') {
          e.preventDefault();
          e.stopPropagation();
          exitSidebar();
          return;
        } else if (e.key === 'ArrowRight' || e.key === 'l') {
          // Expand details or go to link
          e.preventDefault();
          e.stopPropagation();
          if (self.sidebarIndex >= 0) {
            var link = self.sidebarLinks[self.sidebarIndex];
            var details = link.closest('details');
            var summary = link.closest('summary');
            if (summary && details && !details.open) {
              details.open = true;
            } else {
              window.location.href = link.href;
            }
          }
          return;
        } else if (e.key === 'ArrowLeft' || e.key === 'h') {
          // Collapse details or exit sidebar
          e.preventDefault();
          e.stopPropagation();
          if (self.sidebarIndex >= 0) {
            var link = self.sidebarLinks[self.sidebarIndex];
            var details = link.closest('details');
            if (details && details.open) {
              details.open = false;
            } else {
              exitSidebar();
            }
          } else {
            exitSidebar();
          }
          return;
        }
      }
    });
  },

  // Simple linear keyboard navigation - just pass a CSS selector
  initSimpleNav: function(selector, options) {
    options = options || {};
    var elements = Array.from(document.querySelectorAll(selector));
    var selectedIndex = -1;
    var pdfSelector = options.pdfSelector || '[class*="-download-btn"]';
    var self = this;

    function clearSelection() {
      if (selectedIndex >= 0 && selectedIndex < elements.length) {
        elements[selectedIndex].style.outline = '';
        elements[selectedIndex].style.outlineOffset = '';
        elements[selectedIndex].classList.remove('selected');
      }
    }

    function selectElement(index) {
      // Exit sidebar mode if active
      if (self.sidebarActive) {
        self.sidebarActive = false;
        self.sidebarIndex = -1;
        document.querySelectorAll('.nav-sidebar a').forEach(function(link) {
          link.style.outline = '';
          link.style.background = '';
        });
      }
      clearSelection();
      if (elements.length === 0) return;
      selectedIndex = Math.max(0, Math.min(index, elements.length - 1));
      elements[selectedIndex].style.outline = '2px solid #4a7c59';
      elements[selectedIndex].style.outlineOffset = '8px';
      elements[selectedIndex].classList.add('selected');
      elements[selectedIndex].scrollIntoView({ behavior: 'auto', block: 'center' });
    }

    // Store reference for sidebar to clear
    var navInstance = { elements: elements, selectElement: selectElement, clearSelection: clearSelection };
    self.currentPageNav = navInstance;

    document.addEventListener('keydown', function(e) {
      if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
      // Don't handle if sidebar is active (except 'n' is handled above)
      if (self.sidebarActive) return;

      if (e.key === 'ArrowDown' || e.key === 'j') {
        e.preventDefault();
        if (selectedIndex < 0 || KJVNav.isSelectionOffScreen(elements, selectedIndex)) {
          selectElement(KJVNav.findFirstVisibleIndex(elements));
        } else {
          selectElement(selectedIndex + 1);
        }
      } else if (e.key === 'ArrowUp' || e.key === 'k') {
        e.preventDefault();
        if (selectedIndex < 0 || KJVNav.isSelectionOffScreen(elements, selectedIndex)) {
          selectElement(KJVNav.findFirstVisibleIndex(elements));
        } else {
          selectElement(selectedIndex - 1);
        }
      } else if (e.key === 'ArrowLeft' || e.key === 'h') {
        e.preventDefault();
        history.back();
      } else if (e.key === 'Enter') {
        e.preventDefault();
        if (selectedIndex >= 0) {
          var el = elements[selectedIndex];
          var link = el.tagName === 'A' ? el : el.querySelector('a');
          if (link) window.location.href = link.href;
        }
      } else if (e.key === 'Escape') {
        e.preventDefault();
        clearSelection();
        selectedIndex = -1;
      } else if (e.key === 'p') {
        e.preventDefault();
        var pdfBtn = document.querySelector(pdfSelector);
        if (pdfBtn) window.location.href = pdfBtn.href;
      } else if (e.key === ' ') {
        e.preventDefault();
        if (selectedIndex >= 0 && window.KJVSpeech) {
          var text = elements[selectedIndex].textContent || elements[selectedIndex].innerText;
          KJVSpeech.speak(text);
        }
      }
    });

    return navInstance;
  },

  // 2D Grid navigation for card grids - handles up/down by row, left/right within row
  initGridNav: function(selector, options) {
    options = options || {};
    var gridSelector = options.gridSelector || '.book-grid, .topic-grid, .resource-grid, .story-grid, .card-grid';
    var elements = Array.from(document.querySelectorAll(selector));
    var selectedIndex = -1;
    var self = this;

    function getGridColumns() {
      var grid = document.querySelector(gridSelector);
      if (!grid) return 1;
      var style = getComputedStyle(grid);
      var cols = style.gridTemplateColumns.split(' ').length;
      return cols || 1;
    }

    function clearSelection() {
      if (selectedIndex >= 0 && selectedIndex < elements.length) {
        elements[selectedIndex].style.outline = '';
        elements[selectedIndex].style.outlineOffset = '';
        elements[selectedIndex].classList.remove('selected');
      }
    }

    function selectElement(index) {
      // Exit sidebar mode if active
      if (self.sidebarActive) {
        self.sidebarActive = false;
        self.sidebarIndex = -1;
        document.querySelectorAll('.nav-sidebar a').forEach(function(link) {
          link.style.outline = '';
          link.style.background = '';
        });
      }
      clearSelection();
      if (elements.length === 0) return;
      selectedIndex = Math.max(0, Math.min(index, elements.length - 1));
      elements[selectedIndex].style.outline = '2px solid #4a7c59';
      elements[selectedIndex].style.outlineOffset = '4px';
      elements[selectedIndex].classList.add('selected');
      elements[selectedIndex].scrollIntoView({ behavior: 'auto', block: 'center' });
    }

    // Store reference for sidebar to clear
    var navInstance = { elements: elements, selectElement: selectElement, clearSelection: clearSelection };
    self.currentPageNav = navInstance;

    document.addEventListener('keydown', function(e) {
      if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
      if (self.sidebarActive) return;

      var cols = getGridColumns();

      if (e.key === 'ArrowDown' || e.key === 'j') {
        e.preventDefault();
        if (selectedIndex < 0) {
          selectElement(0);
        } else {
          selectElement(selectedIndex + cols);
        }
      } else if (e.key === 'ArrowUp' || e.key === 'k') {
        e.preventDefault();
        if (selectedIndex < 0) {
          selectElement(0);
        } else if (selectedIndex - cols >= 0) {
          selectElement(selectedIndex - cols);
        }
      } else if (e.key === 'ArrowRight' || e.key === 'l') {
        e.preventDefault();
        if (selectedIndex < 0) {
          selectElement(0);
        } else {
          selectElement(selectedIndex + 1);
        }
      } else if (e.key === 'ArrowLeft' || e.key === 'h') {
        e.preventDefault();
        if (selectedIndex <= 0) {
          history.back();
        } else {
          selectElement(selectedIndex - 1);
        }
      } else if (e.key === 'Enter') {
        e.preventDefault();
        if (selectedIndex >= 0) {
          var el = elements[selectedIndex];
          var link = el.tagName === 'A' ? el : el.querySelector('a');
          if (link) window.location.href = link.href;
        }
      } else if (e.key === 'Escape') {
        e.preventDefault();
        clearSelection();
        selectedIndex = -1;
      } else if (e.key === ' ') {
        e.preventDefault();
        if (selectedIndex >= 0 && window.KJVSpeech) {
          var text = elements[selectedIndex].textContent || elements[selectedIndex].innerText;
          KJVSpeech.speak(text);
        }
      }
    });

    return navInstance;
  }
};

// Initialize sidebar navigation globally
document.addEventListener('DOMContentLoaded', function() {
  KJVNav.initSidebarNav();
});

// Text-to-speech for any selected content
window.KJVSpeech = {
  utterance: null,
  speaking: false,

  speak: function(text) {
    if (!('speechSynthesis' in window)) {
      console.log('Speech synthesis not supported');
      return;
    }

    // Stop any current speech
    this.stop();

    // Clean up the text - remove verse numbers at start, collapse whitespace
    text = text.replace(/^\s*\d+\s*/, '').replace(/\s+/g, ' ').trim();

    if (!text) return;

    this.utterance = new SpeechSynthesisUtterance(text);
    this.utterance.rate = 0.9;
    this.utterance.pitch = 1;

    // Try to use a good English voice
    var voices = speechSynthesis.getVoices();
    var englishVoice = voices.find(function(v) {
      return v.lang.startsWith('en') && v.name.includes('Daniel');
    }) || voices.find(function(v) {
      return v.lang.startsWith('en-GB');
    }) || voices.find(function(v) {
      return v.lang.startsWith('en');
    });

    if (englishVoice) {
      this.utterance.voice = englishVoice;
    }

    this.speaking = true;

    this.utterance.onend = function() {
      KJVSpeech.speaking = false;
    };

    this.utterance.onerror = function() {
      KJVSpeech.speaking = false;
    };

    speechSynthesis.speak(this.utterance);
  },

  stop: function() {
    if ('speechSynthesis' in window) {
      speechSynthesis.cancel();
    }
    this.speaking = false;
  },

  toggle: function(text) {
    if (this.speaking) {
      this.stop();
    } else {
      this.speak(text);
    }
  },

  // Get text from the currently selected element (green box)
  getSelectedText: function() {
    // Find element with our green selection outline
    var selected = document.querySelector('[style*="outline: 2px solid"]') ||
                   document.querySelector('[style*="outline:2px solid"]');

    if (selected) {
      return selected.textContent || selected.innerText;
    }

    // Fallback: Try specific verse selectors
    var verseEl = document.querySelector('.verse-text-content') ||
                  document.querySelector('.verse-display .text') ||
                  document.querySelector('.verse-text') ||
                  document.querySelector('[data-verse-text]');

    if (verseEl) {
      return verseEl.textContent || verseEl.innerText;
    }

    return null;
  }
};

// Simple resource reader state (for resource pages)
window.KJVResourceSpeech = {
  speaking: false,
  utterance: null,
  suppressSpace: false
};

// Load voices (they may not be available immediately)
if ('speechSynthesis' in window) {
  speechSynthesis.getVoices();
  speechSynthesis.onvoiceschanged = function() {
    speechSynthesis.getVoices();
  };
}

// Default resource reader unless explicitly disabled
document.addEventListener('DOMContentLoaded', function() {
  if (document.body && !document.body.dataset.resourceReader) {
    document.body.dataset.resourceReader = 'true';
  }
});

// Keyboard shortcuts
document.addEventListener('keydown', function(e) {
  // Don't trigger if user is typing in an input field
  if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') {
    // Allow Escape to clear focus
    if (e.key === 'Escape') {
      e.target.blur();
    }
    return;
  }

  // Cmd/Ctrl + D: Toggle dark mode
  if ((e.metaKey || e.ctrlKey) && e.key === 'd') {
    e.preventDefault();
    toggleDarkMode();
  }

  // Cmd/Ctrl + S: Toggle star (overrides browser save)
  if ((e.metaKey || e.ctrlKey) && e.key === 's') {
    e.preventDefault();
    toggleBookmark();
  }

  // Cmd/Ctrl + K or /: Focus search
  if (((e.metaKey || e.ctrlKey) && e.key === 'k') || e.key === '/') {
    e.preventDefault();
    window.location.href = '/search';
  }

  // Single key shortcuts for navigation (only work without modifiers)
  if (!e.metaKey && !e.ctrlKey && !e.altKey) {
    switch(e.key) {
      case '0':
        e.preventDefault();
        window.location.href = '/';
        break;
      case '1':
        e.preventDefault();
        window.location.href = '/book/Genesis';
        break;
      case '2':
        e.preventDefault();
        window.location.href = '/book/Matthew';
        break;
      case '3':
        e.preventDefault();
        window.location.href = '/book/John';
        break;
      case '4':
        e.preventDefault();
        window.location.href = '/book/Romans';
        break;
      case '7':
        e.preventDefault();
        window.location.href = '/book/Psalms';
        break;
      case '8':
        e.preventDefault();
        window.location.href = '/book/Proverbs';
        break;
      case '9':
        e.preventDefault();
        window.location.href = '/book/Revelation';
        break;
      case 'g':
        e.preventDefault();
        showVerseLookup();
        break;
      case 'r':
        e.preventDefault();
        window.location.href = '/resources';
        break;
      case 'b':
        e.preventDefault();
        window.location.href = '/books';
        break;
      case 's':
        e.preventDefault();
        window.location.href = '/stars';
        break;
      case '/':
        e.preventDefault();
        window.location.href = '/search';
        break;
      case 't':
        e.preventDefault();
        window.location.href = '/topics';
        break;
      case 'p':
        e.preventDefault();
        var pdfBtn = document.querySelector('.pdf-btn, a[href$="/pdf"]');
        if (pdfBtn) window.location.href = pdfBtn.href;
        break;
      case 'f':
        e.preventDefault();
        window.location.href = '/family-tree';
        break;
      case 'c':
        e.preventDefault();
        window.location.href = '/strongs';
        break;
      case 'v':
        e.preventDefault();
        window.location.href = '/verse-of-the-day';
        break;
      case '.':
        e.preventDefault();
        window.location.href = '/random-verse';
        break;
      case '?':
        showKeyboardHelp();
        break;
      case 'R':
        e.preventDefault();
        toggleRedLetters();
        break;
      case ' ':
        // Space: Read aloud selected text (with optional resource-reader handling)
        if (document.body && document.body.dataset && document.body.dataset.resourceReader === 'false') {
          // explicitly disabled
        } else if (document.body) {
          e.preventDefault();
          if (window.KJVResourceSpeech.suppressSpace) return;
          if (!('speechSynthesis' in window)) return;
          // If something is currently speaking or queued, stop it instead of starting a new read
          if (window.KJVResourceSpeech.utterance && (speechSynthesis.speaking || speechSynthesis.pending || speechSynthesis.paused)) {
            speechSynthesis.cancel();
            window.KJVResourceSpeech.speaking = false;
            window.KJVResourceSpeech.utterance = null;
            window.KJVResourceSpeech.suppressSpace = true;
            return;
          }
          if (window.KJVResourceSpeech.speaking) {
            speechSynthesis.cancel();
            window.KJVResourceSpeech.speaking = false;
            window.KJVResourceSpeech.utterance = null;
            window.KJVResourceSpeech.suppressSpace = true;
            return;
          }
          var highlighted = document.querySelector('[style*=\"outline: 2px solid\"]:not(.toc):not(.breadcrumb):not(.chapters-section)') ||
                            document.querySelector('[style*=\"outline:2px solid\"]:not(.toc):not(.breadcrumb):not(.chapters-section)') ||
                            document.querySelector('.selected:not(.toc):not(.breadcrumb):not(.chapters-section)');
          var combined = '';
          if (highlighted) {
            var hclone = highlighted.cloneNode(true);
            hclone.querySelectorAll('.sidenote, .marginnote, .sidenote-number, .margin-toggle, .breadcrumb, .toc, .chapters-section, script, style').forEach(function(el) { el.remove(); });
            combined = (hclone.textContent || hclone.innerText || '').trim();
          } else {
            var article = document.querySelector('article');
            if (article) {
              // If this is a card grid, concatenate the highlighted or first card
              var selectedCard = article.querySelector('.resource-card[style*=\"outline\"]') || article.querySelector('.resource-card');
              if (selectedCard) {
                var cclone = selectedCard.cloneNode(true);
                cclone.querySelectorAll('.sidenote, .marginnote, .sidenote-number, .margin-toggle, .breadcrumb, .toc, .chapters-section, script, style').forEach(function(el) { el.remove(); });
                combined = (cclone.textContent || cclone.innerText || '').trim();
              } else {
                // Prefer reading substantive text blocks instead of the whole article
                var textBlocks = Array.from(article.querySelectorAll('h1, h2, h3, p, li, blockquote, .intro-text, .verse-text, .resource-description, .resource-description-body, .resource-item-description, .parable-description, .angel-description, .covenant-description, .festival-description, .prophet-description, .fruit-description, .name-description, .woman-description, .apostle-description'))
                  .filter(function(el) {
                    if (el.closest('.toc') || el.closest('.chapters-section') || el.closest('.breadcrumb')) return false;
                    var txt = (el.textContent || el.innerText || '').trim();
                    return txt.length > 120;
                  })
                  .map(function(el) {
                    var clone = el.cloneNode(true);
                    clone.querySelectorAll('.sidenote, .marginnote, .sidenote-number, .margin-toggle, .breadcrumb, .toc, .chapters-section, script, style').forEach(function(x) { x.remove(); });
                    return (clone.textContent || clone.innerText || '').trim();
                  })
                  .filter(Boolean);
                if (textBlocks.length > 0) {
                  combined = textBlocks.join('\\n\\n');
                } else {
                  var aclone = article.cloneNode(true);
                  aclone.querySelectorAll('.sidenote, .marginnote, .sidenote-number, .margin-toggle, .breadcrumb, .toc, .chapters-section, script, style').forEach(function(el) { el.remove(); });
                  combined = (aclone.textContent || aclone.innerText || '').trim();
                }
              }
            }
          }
          if (combined) {
            var utter = new SpeechSynthesisUtterance(combined);
            var voices = speechSynthesis.getVoices();
            var englishVoice = voices.find(function(v) { return v.lang && v.lang.toLowerCase().startsWith('en') && v.name.includes('Daniel'); }) ||
                               voices.find(function(v) { return v.lang && v.lang.toLowerCase().startsWith('en-gb'); }) ||
                               voices.find(function(v) { return v.lang && v.lang.toLowerCase().startsWith('en'); });
            if (englishVoice) utter.voice = englishVoice;
            utter.onend = function() {
              window.KJVResourceSpeech.speaking = false;
              window.KJVResourceSpeech.utterance = null;
            };
            utter.onerror = function() {
              window.KJVResourceSpeech.speaking = false;
              window.KJVResourceSpeech.utterance = null;
            };
            window.KJVResourceSpeech.speaking = true;
            window.KJVResourceSpeech.utterance = utter;
            window.KJVResourceSpeech.suppressSpace = false;
            speechSynthesis.cancel();
            speechSynthesis.speak(utter);
          }
        } else {
          var selectedText = KJVSpeech.getSelectedText();
          if (selectedText) {
            e.preventDefault();
            KJVSpeech.toggle(selectedText);
          }
        }
        break;
    }
  }
});

// Clear suppression after spacebar is released
document.addEventListener('keyup', function(e) {
  if (e.key === ' ') {
    window.KJVResourceSpeech.suppressSpace = false;
  }
});

// Quick verse lookup
function showVerseLookup() {
  var reference = prompt('Enter verse reference (e.g., John 3:16, Rev 22 20, Psalm 23, Genesis 1):');
  if (!reference) return;

  reference = reference.trim();

  // Try to match: Book Chapter:Verse (with colon)
  var match = reference.match(/^(.+?)\s+(\d+):(\d+)$/i);
  if (match) {
    var book = match[1].trim();
    var chapter = match[2];
    var verse = match[3];
    window.location.href = '/book/' + encodeURIComponent(book) + '/chapter/' + chapter + '/verse/' + verse;
    return;
  }

  // Try to match: Book Chapter Verse (space instead of colon)
  match = reference.match(/^(.+?)\s+(\d+)\s+(\d+)$/i);
  if (match) {
    var book = match[1].trim();
    var chapter = match[2];
    var verse = match[3];
    window.location.href = '/book/' + encodeURIComponent(book) + '/chapter/' + chapter + '/verse/' + verse;
    return;
  }

  // Try to match: Book Chapter
  match = reference.match(/^(.+?)\s+(\d+)$/i);
  if (match) {
    var book = match[1].trim();
    var chapter = match[2];
    window.location.href = '/book/' + encodeURIComponent(book) + '/chapter/' + chapter;
    return;
  }

  // Try to match: Book
  match = reference.match(/^(.+)$/i);
  if (match) {
    var book = match[1].trim();
    window.location.href = '/book/' + encodeURIComponent(book);
    return;
  }
}

// Keyboard shortcuts help modal
function showKeyboardHelp() {
  // Remove existing modal if present
  var existingModal = document.getElementById('keyboard-help-modal');
  if (existingModal) {
    existingModal.remove();
    return;
  }

  var modal = document.createElement('div');
  modal.id = 'keyboard-help-modal';
  modal.innerHTML =
    '<div class="keyboard-help-backdrop"></div>' +
    '<div class="keyboard-help-content">' +
      '<button class="keyboard-help-close" aria-label="Close">&times;</button>' +
      '<h2>Keyboard Shortcuts</h2>' +
      '<div class="keyboard-help-columns">' +
        '<div class="keyboard-help-section">' +
          '<h3>Navigation</h3>' +
          '<div class="shortcut"><kbd>0</kbd><span>Homepage</span></div>' +
          '<div class="shortcut"><kbd>1</kbd><span>Genesis (OT)</span></div>' +
          '<div class="shortcut"><kbd>2</kbd><span>Matthew (NT)</span></div>' +
          '<div class="shortcut"><kbd>3</kbd><span>John</span></div>' +
          '<div class="shortcut"><kbd>4</kbd><span>Romans</span></div>' +
          '<div class="shortcut"><kbd>7</kbd><span>Psalms</span></div>' +
          '<div class="shortcut"><kbd>8</kbd><span>Proverbs</span></div>' +
          '<div class="shortcut"><kbd>9</kbd><span>Revelation</span></div>' +
          '<div class="shortcut"><kbd>b</kbd><span>Books</span></div>' +
          '<div class="shortcut"><kbd>s</kbd><span>Stars</span></div>' +
          '<div class="shortcut"><kbd>r</kbd><span>Resources</span></div>' +
          '<div class="shortcut"><kbd>t</kbd><span>Topics</span></div>' +
          '<div class="shortcut"><kbd>p</kbd><span>PDF (when available)</span></div>' +
          '<div class="shortcut"><kbd>f</kbd><span>Family Tree</span></div>' +
          '<div class="shortcut"><kbd>c</kbd><span>Strong\'s Concordance</span></div>' +
          '<div class="shortcut"><kbd>v</kbd><span>Verse of the Day</span></div>' +
          '<div class="shortcut"><kbd>.</kbd><span>Random Verse</span></div>' +
          '<div class="shortcut"><kbd>g</kbd><span>Quick verse lookup</span></div>' +
        '</div>' +
        '<div class="keyboard-help-section">' +
          '<h3>Page Navigation</h3>' +
          '<div class="shortcut"><kbd>↑</kbd> / <kbd>k</kbd><span>Previous item</span></div>' +
          '<div class="shortcut"><kbd>↓</kbd> / <kbd>j</kbd><span>Next item</span></div>' +
          '<div class="shortcut"><kbd>←</kbd> / <kbd>h</kbd><span>Go back</span></div>' +
          '<div class="shortcut"><kbd>→</kbd> / <kbd>l</kbd><span>Next page</span></div>' +
          '<div class="shortcut"><kbd>Enter</kbd><span>Select / Open</span></div>' +
        '</div>' +
        '<div class="keyboard-help-section">' +
          '<h3>Other</h3>' +
          '<div class="shortcut"><kbd>Space</kbd><span>Read aloud</span></div>' +
          '<div class="shortcut"><kbd>n</kbd><span>Navigate sidebar</span></div>' +
          '<div class="shortcut"><kbd>⌘</kbd>+<kbd>D</kbd><span>Toggle dark mode</span></div>' +
          '<div class="shortcut"><kbd>R</kbd><span>Toggle red letters</span></div>' +
          '<div class="shortcut"><kbd>⌘</kbd>+<kbd>S</kbd><span>Toggle star</span></div>' +
          '<div class="shortcut"><kbd>/</kbd><span>Search</span></div>' +
          '<div class="shortcut"><kbd>?</kbd><span>Show this help</span></div>' +
          '<div class="shortcut"><kbd>Esc</kbd><span>Close / Clear focus</span></div>' +
        '</div>' +
      '</div>' +
    '</div>';

  // Add styles
  var style = document.createElement('style');
  style.textContent =
    '#keyboard-help-modal { position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 10000; display: flex; align-items: center; justify-content: center; }' +
    '.keyboard-help-backdrop { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.5); }' +
    '.keyboard-help-content { position: relative; background: var(--bg-color); border-radius: 8px; padding: 1.5rem 2rem; max-width: 700px; max-height: 90vh; overflow-y: auto; box-shadow: 0 10px 40px rgba(0,0,0,0.3); }' +
    '.keyboard-help-content h2 { margin: 0 0 1rem 0; font-size: 1.4rem; font-weight: 600; }' +
    '.keyboard-help-close { position: absolute; top: 0.75rem; right: 0.75rem; background: none; border: none; font-size: 1.5rem; cursor: pointer; color: var(--text-secondary); padding: 0.25rem 0.5rem; line-height: 1; }' +
    '.keyboard-help-close:hover { color: var(--text-color); }' +
    '.keyboard-help-columns { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5rem; }' +
    '.keyboard-help-section h3 { font-size: 0.85rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-secondary); margin: 0 0 0.75rem 0; padding-bottom: 0.5rem; border-bottom: 1px solid var(--border-color); }' +
    '.shortcut { display: flex; align-items: center; gap: 0.5rem; margin: 0.4rem 0; font-size: 0.9rem; }' +
    '.shortcut kbd { display: inline-block; padding: 0.15rem 0.4rem; font-family: inherit; font-size: 0.8rem; background: var(--code-bg); border: 1px solid var(--border-color-darker); border-radius: 3px; min-width: 1.5rem; text-align: center; }' +
    '.shortcut span { color: var(--text-secondary); }' +
    '@media (max-width: 700px) { .keyboard-help-columns { grid-template-columns: 1fr; } .keyboard-help-content { margin: 1rem; padding: 1rem 1.5rem; } }';
  modal.appendChild(style);

  document.body.appendChild(modal);

  // Close handlers
  modal.querySelector('.keyboard-help-backdrop').addEventListener('click', function() {
    modal.remove();
  });
  modal.querySelector('.keyboard-help-close').addEventListener('click', function() {
    modal.remove();
  });
  document.addEventListener('keydown', function closeOnEsc(e) {
    if (e.key === 'Escape') {
      modal.remove();
      document.removeEventListener('keydown', closeOnEsc);
    }
  });
}

// Verse tooltip functionality
(function() {
  // Remove any existing tooltip (handles bfcache restoration)
  var existingTooltip = document.querySelector('.verse-tooltip');
  if (existingTooltip) {
    existingTooltip.remove();
  }

  // Create tooltip element
  var tooltip = document.createElement('div');
  tooltip.className = 'verse-tooltip';
  document.body.appendChild(tooltip);

  // Cache for fetched verses
  var verseCache = {};

  // Parse verse URL to extract book, chapter, and verse
  function parseVerseUrl(url) {
    // Try to match single verse URL (old format): /book/John/chapter/3/verse/16
    var match = url.match(/\/book\/([^\/]+)\/chapter\/(\d+)\/verse\/(\d+)/);
    if (match) {
      return {
        book: decodeURIComponent(match[1]),
        chapter: match[2],
        verse: match[3],
        verseEnd: null,
        cacheKey: match[1] + '_' + match[2] + '_' + match[3],
        isRange: false
      };
    }

    // Try to match verse range URL: /book/Proverbs/chapter/31#verse-26-28
    match = url.match(/\/book\/([^\/]+)\/chapter\/(\d+)#verse-(\d+)-(\d+)/);
    if (match) {
      return {
        book: decodeURIComponent(match[1]),
        chapter: match[2],
        verse: match[3],
        verseEnd: match[4],
        cacheKey: match[1] + '_' + match[2] + '_' + match[3] + '-' + match[4],
        isRange: true
      };
    }

    // Try to match single verse anchor URL (new format): /book/John/chapter/3#verse-16
    match = url.match(/\/book\/([^\/]+)\/chapter\/(\d+)#verse-(\d+)$/);
    if (match) {
      return {
        book: decodeURIComponent(match[1]),
        chapter: match[2],
        verse: match[3],
        verseEnd: null,
        cacheKey: match[1] + '_' + match[2] + '_' + match[3],
        isRange: false
      };
    }

    return null;
  }

  // Fetch verse text from server using API
  async function fetchVerseText(book, chapter, verse, verseEnd, cacheKey) {
    // Check cache first
    if (verseCache[cacheKey]) {
      return verseCache[cacheKey];
    }

    try {
      var url;

      if (verseEnd) {
        // Use verse range API endpoint
        url = '/api/verse-range/' + encodeURIComponent(book) + '/' + chapter + '/' + verse + '/' + verseEnd;
      } else {
        // Use single verse API endpoint
        url = '/api/verse/' + encodeURIComponent(book) + '/' + chapter + '/' + verse;
      }

      var response = await fetch(url);
      if (!response.ok) throw new Error('Failed to fetch verse');

      var data = await response.json();

      // Cache the result
      verseCache[cacheKey] = {
        reference: data.reference,
        text: data.text
      };

      return verseCache[cacheKey];
    } catch (error) {
      console.error('Error fetching verse:', error);
      return {
        reference: verseEnd ? book + ' ' + chapter + ':' + verse + '-' + verseEnd : book + ' ' + chapter + ':' + verse,
        text: 'Error loading verse'
      };
    }
  }

  // Show tooltip positioned relative to a link element
  function showTooltip(verseData, linkElement) {
    tooltip.innerHTML =
      '<span class="verse-tooltip-reference">' + verseData.reference + '</span>' +
      '<span class="verse-tooltip-text">' + verseData.text + '</span>';

    // Position off-screen first to measure dimensions accurately
    tooltip.style.left = '-9999px';
    tooltip.style.top = '-9999px';
    tooltip.classList.add('show');

    // Force reflow to get accurate dimensions
    var tooltipWidth = tooltip.offsetWidth;
    var tooltipHeight = tooltip.offsetHeight;

    // Get link position
    var linkRect = linkElement.getBoundingClientRect();
    var padding = 10;

    // Position below the link, centered horizontally
    var x = linkRect.left + (linkRect.width / 2) - (tooltipWidth / 2);
    var y = linkRect.bottom + 8 + window.scrollY;

    // Adjust if tooltip goes off right edge
    if (x + tooltipWidth > window.innerWidth - padding) {
      x = window.innerWidth - tooltipWidth - padding;
    }

    // Ensure tooltip doesn't go off left edge
    if (x < padding) {
      x = padding;
    }

    // If tooltip goes off bottom edge, show above the link instead
    if (linkRect.bottom + 8 + tooltipHeight > window.innerHeight) {
      y = linkRect.top - tooltipHeight - 8 + window.scrollY;
    }

    // Ensure tooltip doesn't go off top edge
    if (y < window.scrollY + padding) {
      y = window.scrollY + padding;
    }

    tooltip.style.left = x + 'px';
    tooltip.style.top = y + 'px';
  }

  // Hide tooltip
  function hideTooltip() {
    tooltip.classList.remove('show');
  }

  // Check if we're on a chapter page (tooltips disabled there - sidenotes provide context)
  var isChapterPage = /^\/book\/[^/]+\/chapter\/\d+\/?$/.test(window.location.pathname);

  // Event delegation for verse links
  document.addEventListener('mouseover', function(e) {
    // Skip tooltips entirely on chapter pages
    if (isChapterPage) return;

    var target = e.target;

    // Check if target is a link or inside a link
    if (target.tagName !== 'A') {
      target = target.closest('a');
    }

    if (!target || !target.href) return;

    // Skip if this is a cross-reference link (has its own tooltip system)
    if (target.classList.contains('cross-ref-link')) return;

    // Skip if this is a verse number link (the number at the start of each verse)
    if (target.classList.contains('verse-number-link')) return;

    // Skip links in search dropdowns
    if (target.closest('.search-results-dropdown') || target.closest('.search-dropdown') ||
        target.closest('.lookup-results-dropdown') || target.closest('.story-search-dropdown')) return;

    // Skip links in concordance results (verse text already shown inline)
    if (target.closest('.occurrence-reference') || target.closest('.occurrence')) return;

    // Skip links in cross-references section (has its own CSS tooltip system)
    if (target.closest('.cross-references-section')) return;

    // Skip links in navigation, buttons, actions, headers, and non-content areas
    if (target.closest('nav') || target.closest('header') || target.closest('footer') ||
        target.closest('.toc') || target.closest('.breadcrumb') ||
        target.closest('button') || target.closest('[class*="-btn"]') || target.closest('[class*="-actions"]') ||
        target.closest('[class*="download"]') || target.closest('[class*="print"]') ||
        target.closest('.share-container') || target.closest('.share-buttons') ||
        target.closest('.share-section') || target.closest('.share-pills') ||
        target.closest('.chapter-nav') || target.closest('.verse-nav') ||
        target.closest('h1') || target.closest('h2') || target.closest('h3')) return;

    // Only show tooltips for links inside content paragraphs, sections, or article content
    if (!target.closest('p') && !target.closest('section') && !target.closest('article') &&
        !target.closest('.verse-item') && !target.closest('.verse-text') &&
        !target.closest('.intro-text') && !target.closest('.description') &&
        !target.closest('.sidenote') && !target.closest('.marginnote') &&
        !target.closest('li')) return;

    var verseInfo = parseVerseUrl(target.pathname + target.hash);
    if (!verseInfo) return;

    // Show loading state positioned relative to link
    tooltip.innerHTML = '<span class="verse-tooltip-loading">Loading...</span>';
    var linkRect = target.getBoundingClientRect();
    tooltip.style.left = linkRect.left + 'px';
    tooltip.style.top = (linkRect.bottom + 8 + window.scrollY) + 'px';
    tooltip.classList.add('show');

    // Fetch and display verse
    fetchVerseText(verseInfo.book, verseInfo.chapter, verseInfo.verse, verseInfo.verseEnd, verseInfo.cacheKey)
      .then(function(verseData) {
        // Only show if still hovering
        if (target.matches(':hover')) {
          showTooltip(verseData, target);
        }
      });

    // Hide tooltip on mouse leave
    target.addEventListener('mouseleave', function() {
      hideTooltip();
    }, { once: true });
  });

  // Hide tooltip on page restore from bfcache (Safari fix)
  window.addEventListener('pageshow', function() {
    hideTooltip();
    setTimeout(hideTooltip, 0);
    setTimeout(hideTooltip, 100);
  });
})();

// Site-wide verse linking
(function() {
  function linkVerseReferences(element) {
    if (!element) return;

    // Get all text nodes, but skip those inside anchors (already linked)
    const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT, {
      acceptNode: function(node) {
        // Skip text nodes that are inside anchor tags (already linked)
        if (node.parentNode && node.parentNode.tagName === 'A') {
          return NodeFilter.FILTER_REJECT;
        }
        return NodeFilter.FILTER_ACCEPT;
      }
    }, false);
    const textNodes = [];
    let node;
    while (node = walker.nextNode()) {
      textNodes.push(node);
    }

    textNodes.forEach(function(textNode) {
      let text = textNode.textContent;
      let changed = false;

      // First, handle comma-separated verse lists like "Psalms 7:17, 9:2, 18:13"
      text = text.replace(/\b(\d?\s?[A-Z][a-z]+(?:\s+[A-Z][a-z]+)?)\s+((?:\d+:\d+(?:-\d+)?(?:\s*,\s*)?)+)/g, function(match, book, verseList) {
        book = book.trim();

        if (!verseList.includes(',')) {
          return match;
        }

        changed = true;

        var verses = verseList.split(/\s*,\s*/);
        var links = verses.map(function(verseRef) {
          verseRef = verseRef.trim();
          var parts = verseRef.match(/^(\d+):(\d+)(?:-(\d+))?$/);
          if (parts) {
            var chapter = parts[1];
            var verseStart = parts[2];
            var verseEnd = parts[3];

            if (verseEnd) {
              return '<a href="/book/' + book + '/chapter/' + chapter + '#verse-' + verseStart + '-' + verseEnd + '">' + book + ' ' + chapter + ':' + verseStart + '-' + verseEnd + '</a>';
            } else {
              return '<a href="/book/' + book + '/chapter/' + chapter + '/verse/' + verseStart + '">' + book + ' ' + chapter + ':' + verseStart + '</a>';
            }
          }
          return verseRef;
        });

        return links.join(', ');
      });

      // Then handle individual verse references like "John 3:16" or "Romans 8:28-29"
      text = text.replace(/\b(\d?\s?[A-Z][a-z]+(?:\s+[A-Z][a-z]+)?)\s+(\d+):(\d+)(?:-(\d+))?\b/g, function(match, book, chapter, verseStart, verseEnd) {
        changed = true;
        book = book.trim();
        if (verseEnd) {
          return '<a href="/book/' + book + '/chapter/' + chapter + '#verse-' + verseStart + '-' + verseEnd + '">' + match + '</a>';
        } else {
          return '<a href="/book/' + book + '/chapter/' + chapter + '/verse/' + verseStart + '">' + match + '</a>';
        }
      });

      if (changed) {
        const span = document.createElement('span');
        span.innerHTML = text;
        textNode.parentNode.replaceChild(span, textNode);
        while (span.firstChild) {
          span.parentNode.insertBefore(span.firstChild, span);
        }
        span.parentNode.removeChild(span);
      }
    });
  }

  // Link verses in common content areas
  document.querySelectorAll('.intro-text, .prophet-description, .angel-description, .covenant-description, p, li').forEach(function(element) {
    // Skip if already processed or if it's in the sidebar
    if (element.closest('.nav-sidebar') || element.dataset.verseLinked) {
      return;
    }
    element.dataset.verseLinked = 'true';
    linkVerseReferences(element);
  });
})();

// Prefetch next/prev pages for faster navigation
(function() {
  // Wait for page to be fully loaded and idle
  if ('requestIdleCallback' in window) {
    requestIdleCallback(prefetchNavigationLinks, { timeout: 2000 });
  } else {
    setTimeout(prefetchNavigationLinks, 1000);
  }

  function prefetchNavigationLinks() {
    // Find navigation links (next/prev chapter, verse, book)
    var prefetchSelectors = [
      'a[rel="next"]',
      'a[rel="prev"]',
      '.chapter-nav a',
      '.verse-nav a',
      '.book-nav a',
      '.nav-btn[href*="/chapter/"]',
      '.nav-btn[href*="/verse/"]'
    ];

    var links = document.querySelectorAll(prefetchSelectors.join(', '));
    var prefetched = new Set();

    links.forEach(function(link) {
      var href = link.href;
      if (!href || prefetched.has(href)) return;
      if (href.includes('#')) return; // Skip anchor links
      if (!href.startsWith(window.location.origin)) return; // Skip external links

      prefetched.add(href);

      // Use link prefetch hint
      var prefetchLink = document.createElement('link');
      prefetchLink.rel = 'prefetch';
      prefetchLink.href = href;
      prefetchLink.as = 'document';
      document.head.appendChild(prefetchLink);
    });
  }
})();

