document.addEventListener('DOMContentLoaded', function () {
    const searchForm = document.getElementById('searchForm');
    const searchInput = document.querySelector('.form-control');
    const searchResultsDiv = document.getElementById("searchResultsDiv");
    const closeResultsBtn = document.getElementById("closeResultsBtn");
    const clearSearchInputBtn = document.getElementById('clearSearchInputBtn');
    const resultsWaitMsg = document.getElementById('ResultsWaitMsg');

    // Flag to check if search results are already visible
    let searchResultsVisible = false;

    searchForm.addEventListener('submit', function (event) {
        event.preventDefault();

        // Change cursor to "wait"
        document.body.style.cursor = 'wait';

        // Show the waiting message
        resultsWaitMsg.style.display = 'block';

        const userInput = searchInput.value.trim().toLowerCase();
        performSearch(userInput, function(results) {
            // console.log('Search Results:', results);
            // Call function to display search results with search term
            displaySearchResults(results, userInput);

            if (!searchResultsVisible) {
                showSearchResults(); // Call function to show search results with animation only if not already shown
            }
            searchResultsVisible = true;

            // Hide the waiting message when results are returned
            resultsWaitMsg.style.display = 'none';

            // Reset cursor to default
            document.body.style.cursor = 'default';
        });
    });

    // Add event listener to the clear button
    clearSearchInputBtn.addEventListener('click', function() {
        // Clear the search input field
        searchInput.value = '';
        // Bring focus to the input field
        searchInput.focus();
    });

    // Function to show search results with animation
    function showSearchResults() {
        searchResultsDiv.style.display = 'block'; // Make sure search results div is visible
        searchResultsDiv.style.transform = 'translateX(100%)'; // Start from the right side of the screen
        setTimeout(function() {
            searchResultsDiv.style.transform = 'translateX(0%)'; // Slide back into view

            // Hide the waiting message after results div is shown
            resultsWaitMsg.style.display = 'none';
        }, 50); // Adjust the delay to ensure the animation is visible
    }

    closeResultsBtn.addEventListener('click', function() {
        if (searchResultsVisible) { // Check if search results are currently visible
            searchResultsDiv.style.transform = 'translateX(100%)'; // Slide to the right
            setTimeout(function() {
                searchResultsDiv.style.display = 'none'; // Hide the element after the animation completes
            }, 300); // Adjust the timeout to match the transition duration
            searchResultsVisible = false;
        }
    });

    // function performSearch(searchQuery, callback) {
    //     console.log('Performing search for query:', searchQuery);
    //     fetchIndexData().then(indexData => {
    //         const results = [];
    //         let totalMatches = 0; // Variable to keep track of total matches found
    //         for (const productIdentifier in indexData) {
    //             // Filter out records with '`Reuse' in the path
    //             if (indexData[productIdentifier].Path.includes('`Reuse')) {
    //                 // console.log('Skipping productIdentifier containing `Reuse` in path:', productIdentifier);
    //                 continue;
    //             }
    //             const htmlContent = indexData[productIdentifier].Content.value;
    //             const parser = new DOMParser();
    //             const doc = parser.parseFromString(htmlContent, 'text/html');
    //             const text = doc.body.textContent || '';
    //             const matches = text.match(new RegExp(searchQuery, 'gi')); // Use RegExp to find all matches
    //             if (matches && matches.length > 0) {
    //                 totalMatches += matches.length; // Increment total matches count
    //                 results.push(indexData[productIdentifier]); // Push entire object to results
    //             }
    //         }
    //         // console.log('Total matches found:', totalMatches);
    //         callback(results);
    //     }).catch(error => {
    //         console.error('Error fetching index data:', error);
    //         callback([]);
    //     });
    // }

    function performSearch(searchQuery, callback) {
        console.log('Performing search for query:', searchQuery);
        fetchIndexData().then(indexData => {
          const results = [];
          for (const entry of indexData) {
            const htmlContent = entry.Content.value;
            const parser = new DOMParser();
            const doc = parser.parseFromString(htmlContent, 'text/html');
            const text = doc.body.textContent || '';

            // Check if the search term occurs within any level of parent 'wh_publication_toc'
            if (!isTermInParentElement(doc, searchQuery, 'wh_publication_toc')) {
                continue; // Skip this entry if the term occurs within 'wh_publication_toc'
            }
      
            // Check if "Whole word match" checkbox is checked
            const wholeWordMatch = document.getElementById('wholeWordMatch').checked;
      
            let matches;
            if (wholeWordMatch) {
              // Use a word boundary metacharacter (`\b`) for whole word match
              matches = (text.match(new RegExp(`\\b${searchQuery}\\b`, 'gi')) || []).length;
            } else {
              matches = (text.match(new RegExp(searchQuery, 'gi')) || []).length;
            }
      
            if (matches && matches > 0) {
              entry.relevanceScore = matches;
              results.push(entry);
            }
          }
      
          // Sort results by relevance score in descending order
          results.sort((a, b) => b.relevanceScore - a.relevanceScore);
      
          callback(results);
        }).catch(error => {
          console.error('Error fetching index data:', error);
          callback([]);
        });
      }
      
    

    function fetchIndexData() {
        const productIdentifier = getProductIdentifier();
        const indexPath = `s-index.json`;

        return fetch(indexPath)
            .then(response => {
                if (response.ok) {
                    return response.json();
                } else if (response.status === 404) {
                    return fetchAndCreateIndexFile(productIdentifier);
                } else {
                    throw new Error(`Error fetching index data. Status: ${response.status}, URL: ${indexPath}`);
                }
            })
            .then(data => {
                return data;
            })
            .catch(error => console.error('Error fetching index data:', error));
    }

    function fetchAndCreateIndexFile(productIdentifier) {
        return fetch(`/resources/landingpages/js/${productIdentifier}_searchIndexData.json`)
            .then(response => {
                if (response.ok) {
                    return response.json();
                } else if (response.status === 404) {
                    console.warn(`Index data file not found for ${productIdentifier}. Creating an empty index.`);
                    return {};
                } else {
                    throw new Error(`Error fetching index data. Status: ${response.status}`);
                }
            })
            .then(indexData => {
                const blob = new Blob([JSON.stringify(indexData)], { type: 'application/json' });

                const link = document.createElement('a');
                link.href = URL.createObjectURL(blob);
                link.download = `${productIdentifier}_searchIndex.json`;

                link.click();

                return indexData;
            })
            .catch(error => {
                console.error('Error fetching and creating index file:', error);
                return {};
            });
    }

    function getProductIdentifier() {
        const currentPath = window.location.pathname;
        return currentPath.split('/')[2];
    }
});


// Helper function to check if the search term occurs within any level of parent 'wh_publication_toc'
function isTermInParentElement(doc, term, parentId) {
    const parentElement = doc.getElementById(parentId);
    if (parentElement && parentElement.textContent.toLowerCase().includes(term.toLowerCase())) {
        return true; // Return true if the term is found within the parent element
    }
    return false; // Return false if the term is not found within the parent element
}

function displaySearchResults(searchResults, searchTerm) {
    // Get all radio buttons with the class 'sortOption'
    const radioButtons = document.querySelectorAll('.sortOption');

    // Iterate through the radio buttons and disable them
    radioButtons.forEach(button => {
        button.disabled = true;
    });

    // Get the search results div element
    const searchResultsDiv = document.getElementById("searchResultsDiv");

    // Check if the header already exists
    let searchResultsHeader = searchResultsDiv.querySelector(".search-results-header");

    // If the header doesn't exist, create it
    if (!searchResultsHeader) {
        // Create a new div element for the header
        searchResultsHeader = document.createElement("div");
        searchResultsHeader.classList.add("search-results-header");

        // Create HTML content for the header
        const headerContent = `
            <h2>Search Results</h2>
            <button id="closeResultsBtn" class="close-results-btn">×</button>
        `;

        // Set the inner HTML of the header div
        searchResultsHeader.innerHTML = headerContent;

        // Append the header div to the search results div
        searchResultsDiv.appendChild(searchResultsHeader);
    }

    // Get the search results container
    const searchResultsContainer = document.getElementById("searchResultsContainer");

    // Clear any previous search results
    searchResultsContainer.innerHTML = "";

    // If no results were found, display a message
    if (searchResults.length === 0) {
        const noResultsMessage = document.createElement("p");
        noResultsMessage.innerHTML = `Your search returned no results for <strong>${searchTerm}</strong>`;
        noResultsMessage.id = "resultNotFound"; // Add id to the resulting paragraph element
        searchResultsContainer.appendChild(noResultsMessage);
        return; // Stop execution since there are no results to display
    }

    // Add a count of the number of results and display it at the top
    const resultsCount = document.createElement("p");
    resultsCount.innerHTML = `${searchResults.length} document(s) found for <strong>${searchTerm}</strong>`;
    resultsCount.id = "resultsFound";
    searchResultsContainer.appendChild(resultsCount);

    // Sort search results based on your criteria
    searchResults.sort((a, b) => {

        // 1. Term Frequency (higher frequency comes first)
        const termFreqA = countTermFrequency(a.Content.value, searchTerm);
        const termFreqB = countTermFrequency(b.Content.value, searchTerm);
        if (termFreqB !== termFreqA) {
        return termFreqB - termFreqA; // Descending order for frequency
        }

        // 2. Document Type (Documents without Release Notes/Changelog prioritized)
        const isReleaseNoteA = a.Title.toLowerCase().includes("release note") || a.Title.toLowerCase().includes("changelog");
        const isReleaseNoteB = b.Title.toLowerCase().includes("release note") || b.Title.toLowerCase().includes("changelog");
        if (isReleaseNoteA !== isReleaseNoteB) {
        return isReleaseNoteA ? 1 : -1; // Documents with Release Notes/Changelog have lower priority
        }

        // 3. Term Proximity (closer to beginning comes first)
        const firstTermIndexA = a.Content.value.toLowerCase().indexOf(searchTerm.toLowerCase());
        const firstTermIndexB = b.Content.value.toLowerCase().indexOf(searchTerm.toLowerCase());
        if (firstTermIndexA !== firstTermIndexB) {
        return firstTermIndexA - firstTermIndexB; // Lower index (closer to beginning) prioritizes higher
        }

        // If all criteria are equal, return 0 (no change in order)
        return 0;
    });

    // Loop through the sorted search results and create HTML elements to display them
    searchResults.forEach(result => {
        // Modify the link if the base path of the result includes '/dev/' or '\dev\'
        let link = result.Link + `?hl=${encodeURIComponent(searchTerm)}`;
        if (link.includes('/dev/') || link.includes('\\dev\\')) {
            link = link.replace(/^.*?[\/\\]dev[\/\\]/i, 'https://dev-documentation.wolterskluwerfs.com/');
        }
        if (link.includes('/stg/') || link.includes('\\stg\\')) {
            link = link.replace(/^.*?[\/\\]stg[\/\\]/i, 'https://stg-documentation.wolterskluwerfs.com/');
        }
        if (link.includes('/tst/') || link.includes('\\tst\\')) {
            link = link.replace(/^.*?[\/\\]tst[\/\\]/i, 'https://tst-documentation.wolterskluwerfs.com/');
        }
        if (link.includes('/prod/') || link.includes('\\prod\\')) {
            link = link.replace(/^.*?[\/\\]prod[\/\\]/i, 'https://documentation.wolterskluwerfs.com/');
        }
        if (link.includes('/tst-expere/') || link.includes('\\tst-expere\\')) {
            link = link.replace(/^.*?[\/\\]tst-expere[\/\\]/i, 'https://tst-expere-documentation.wolterskluwerfs.com/');
        }

        // Create a new div element for each search result
        const resultDiv = document.createElement("div");
        resultDiv.classList.add("search-result");

        // Calculate percentage relevance (for the stars image background)
        const maxRelevanceScore = 20; // Assuming maximum relevance score is 20
        const relevancePercentage = ((result.relevanceScore / maxRelevanceScore) * 100).toFixed(3); // Format to 3 decimal places

        // Check if the "Omit < 10%" checkbox is checked
        const omitLessThanTenPercentCheckbox = document.getElementById("omitLessThanTenPercent");
        const omitLessThanTenPercent = omitLessThanTenPercentCheckbox.checked;

        // Skip results with relevance percentage below 10% if the checkbox is checked
        if (omitLessThanTenPercent && relevancePercentage < 10) {
            return; // Skip this result
        }

        // Extracting the sentence containing the search term
        const relevantSentence = extractRelevantSentence(result.Content.value, searchTerm);

        // Truncate the sentence to 100 characters with an ellipsis if necessary
        const shortDesc = relevantSentence.length > 100 ? relevantSentence.substring(0, 100) + "..." : relevantSentence;

        // Create HTML content for the search result
        const resultContent = `
            <div class="result-details">
                <p class="searchResultTitle"><a href="${link}" target="_blank">${result.Title}</a></p>
                <div class="rel-doc-container">
                    <p class="RelDocTitle">${result.Document}</p>
                    <div class="stars-container" style="background: linear-gradient(to right, #FFD700 ${relevancePercentage}%, transparent ${relevancePercentage}%); width:77px; height: 14px;" title="Relevance: ${relevancePercentage}%">
                        <img src="/resources/landingpages/images/outlined-stars.png" alt="Relevance Stars" class="stars-image" style="vertical-align: top;">
                    </div>
                </div>
                <!--<div class="shortDesc">${shortDesc}</div>-->
            </div>
        `;

        // Set the inner HTML of the result div
        resultDiv.innerHTML = resultContent;

        // Append the result div to the search results container
        searchResultsContainer.appendChild(resultDiv);
    });

    // Create a footer element
    const footer = document.createElement("footer");
    footer.innerHTML = ""; // You can customize the content of the footer here
    footer.classList.add("searchResultsFooter");
    footer.id = "searchResultsFooter";

    // Append the footer to the search results container
    searchResultsContainer.appendChild(footer);
    
}


// Helper function to count the number of times a term appears in a string
function countTermFrequency(content, term) {
    const regex = new RegExp(term, "gi");
    return content.match(regex)?.length || 0; // Return 0 if no matches found
}



function extractRelevantSentence(content, searchTerm) {
    const parser = new DOMParser();
    const doc = parser.parseFromString(content, 'text/html');
    const textContent = doc.body.textContent || ''; // Extract text content while preserving basic formatting
  
    // Split the text content into an array of words
    const words = textContent.split(/\s+/); // Split by whitespace (including punctuation)
  
    // Find the index of the first exact match of the search term
    const termIndex = words.indexOf(searchTerm.toLowerCase());
  
    // If the search term is found
    if (termIndex !== -1) {
      let start = termIndex - 1;
      let end = termIndex + 1;
  
      // Find the beginning of the sentence before the term
      while (start >= 0 && !isSentenceEnd(words[start])) {
        start--;
      }
  
      // Find the end of the sentence after the term
      while (end < words.length && !isSentenceEnd(words[end])) {
        end++;
      }
  
      // Join the window of words back into a sentence
      const relevantSentence = words.slice(Math.max(0, start + 1), end).join(" ");
  
      // Return the extracted sentence
      return relevantSentence.trim();
    }
  
    // If no exact match is found, return an empty string
    return "";
  }
  
  function isSentenceEnd(word) {
    return word.includes(".") || word.includes("?") || word.includes("!");
  }
    

function toggleResultsInfo() {
    // Toggle the visibility of the resultsInfo div
    $('#resultsInfo').toggle();
}

// Function to close the resultsInfo div
function closeResultsInfo() {
    // Hide the resultsInfo div
    $('#resultsInfo').hide();
}

document.getElementById('sortByTermFrequencyBtn').addEventListener('click', function(event) {
    event.preventDefault(); // Prevent the default behavior of the link
    sortByTermFrequency();
});

document.getElementById('sortByDocumentType').addEventListener('click', function(event) {
    event.preventDefault(); // Prevent the default behavior of the link
    sortByDocumentType();
});

document.getElementById('omitLtTenPercent').addEventListener('click', function(event) {
    event.preventDefault(); // Prevent the default behavior of the link
    removeResultsBelowTenPercent();
});


// Function to sort results by term frequency
function sortByTermFrequency() {
    // Get the search results container
    var container = document.getElementById('searchResultsContainer');

    // Get the search results footer
    var footer = document.getElementById('searchResultsFooter');

    // Get all search result elements
    var results = container.querySelectorAll('.search-result');

    // Convert NodeList to array for sorting
    var resultsArray = Array.from(results);

    // Sort the array of search result elements based on relevance
    resultsArray.sort(function(a, b) {
        // Get the relevance values from the stars-container elements
        var relevanceA = parseFloat(a.querySelector('.stars-container').getAttribute('title').match(/\d+\.\d+/)[0]);
        var relevanceB = parseFloat(b.querySelector('.stars-container').getAttribute('title').match(/\d+\.\d+/)[0]);

        // Sort in descending order
        return relevanceB - relevanceA;
    });

    // Re-append the sorted elements to the container
    resultsArray.forEach(function(result) {
        container.appendChild(result);
    });

    // Move the footer to the bottom of the container
    container.appendChild(footer);
}


function sortByDocumentType() {
    // Get the search results container
    var container = document.getElementById('searchResultsContainer');

    // Get the search results footer
    var footer = document.getElementById('searchResultsFooter');

    // Get all search result elements
    var results = container.querySelectorAll('.search-result');

    // Convert NodeList to array for sorting
    var resultsArray = Array.from(results);

    // Sort the array of search result elements based on the RelDocTitle
    resultsArray.sort(function(a, b) {
        var titleA = a.querySelector('.RelDocTitle').textContent.trim().toLowerCase();
        var titleB = b.querySelector('.RelDocTitle').textContent.trim().toLowerCase();

        // Define sorting logic
        if (titleA.includes('release notes') || titleA.includes('changelog')) {
            return 1; // Move items with "Release Notes" or "Changelog" to the end
        } else if (titleB.includes('release notes') || titleB.includes('changelog')) {
            return -1; // Move items with "Release Notes" or "Changelog" to the end
        } else {
            return titleA.localeCompare(titleB); // Sort alphabetically
        }
    });

    // Re-append the sorted elements to the container
    resultsArray.forEach(function(result) {
        container.appendChild(result);
    });

    // Move the footer to the bottom of the container
    container.appendChild(footer);
}

function removeResultsBelowTenPercent() {
    // Get the search results container
    var container = document.getElementById('searchResultsContainer');

    // Get all search result elements
    var results = container.querySelectorAll('.search-result');

    // Iterate through each search result
    results.forEach(function(result) {
        // Get the relevance value from the stars-container element
        var relevance = parseFloat(result.querySelector('.stars-container').getAttribute('title').match(/\d+\.\d+/)[0]);

        // Check if relevance is less than 10%
        if (relevance < 10) {
            // Remove the search result
            result.remove();
        }
    });
}


//#region Search Options
// Get the search options button
const searchOptionsBtn = document.getElementById('searchOptionsBtn');

// Get the custom search options container
const customSearchOptions = document.getElementById('customSearchOptions');

// Add event listener to toggle the display
searchOptionsBtn.addEventListener('click', function() {
    // Toggle the display of custom search options
    if (customSearchOptions.style.display === 'none') {
        customSearchOptions.style.display = 'block';
    } else {
        customSearchOptions.style.display = 'none';
    }
});
//#endregion


//#region Whole Word match
// Get references to the checkboxes
const wholeWordMatchCheckbox = document.getElementById('wholeWordMatch');
const wholeWordMatch2Checkbox = document.getElementById('wholeWordMatch2');

// Add event listeners to synchronize the toggling behavior
wholeWordMatchCheckbox.addEventListener('change', function() {
    wholeWordMatch2Checkbox.checked = this.checked;
});

wholeWordMatch2Checkbox.addEventListener('change', function() {
    wholeWordMatchCheckbox.checked = this.checked;
});

// Add event listener to the wholeWordMatch checkbox
document.getElementById('wholeWordMatch').addEventListener('change', function() {
    // Get the search term from the search input field
    const searchTerm = document.querySelector('.form-control').value.trim().toLowerCase();

    // Get all search result elements
    const results = document.querySelectorAll('.search-result');

    // Iterate through each search result
    results.forEach(result => {
        // Get the title and content of the search result
        const title = result.querySelector('.searchResultTitle').textContent.trim().toLowerCase();
        const content = result.querySelector('.result-details').textContent.trim().toLowerCase();

        // Check if the wholeWordMatch checkbox is checked
        const wholeWordMatchChecked = document.getElementById('wholeWordMatch').checked;

        // If wholeWordMatch is checked and the result doesn't match the search term exactly, hide it
        if (wholeWordMatchChecked && !isWholeWordMatch(title, searchTerm) && !isWholeWordMatch(content, searchTerm)) {
            result.style.display = 'none';
        } else {
            result.style.display = 'block';
        }
    });
});

document.getElementById('wholeWordMatch2').addEventListener('change', function() {
    // Get the search term from the search input field
    const searchTerm = document.querySelector('.form-control').value.trim().toLowerCase();

    // Get all search result elements
    const results = document.querySelectorAll('.search-result');

    // Iterate through each search result
    results.forEach(result => {
        // Get the title and content of the search result
        const title = result.querySelector('.searchResultTitle').textContent.trim().toLowerCase();
        const content = result.querySelector('.result-details').textContent.trim().toLowerCase();

        // Check if the wholeWordMatch checkbox is checked
        const wholeWordMatchChecked = document.getElementById('wholeWordMatch').checked;

        // If wholeWordMatch is checked and the result doesn't match the search term exactly, hide it
        if (wholeWordMatchChecked && !isWholeWordMatch(title, searchTerm) && !isWholeWordMatch(content, searchTerm)) {
            result.style.display = 'none';
        } else {
            result.style.display = 'block';
        }
    });
});

// Helper function to check if a term is a whole word match
function isWholeWordMatch(text, term) {
    // Create a regular expression pattern to match the whole word
    const regex = new RegExp("\\b" + term + "\\b", "gi"); // \b represents a word boundary

    // Check if the term is found in the text
    return text.match(regex) !== null;
}
//#endregion