const BACKEND_BASE_URL = "https://snts-app.herokuapp.com";
const LOCATOR_EXPAND_MIN_WIDTH = 901;
let iconPosition = "right";
let shopUrl = "";
let storeLocations = [];
let filteredStoreLocations = [];
let storeCoordinates = {};
let storeIndexMap = new Map();
let isExpandedState = {};
let isStoresListCollapsed = false;
let storesListMediaQuery = null;
let selectedStoreId = null;
let expandDesktopMediaQuery = null;
let isLocatorExpanded = false;

document.addEventListener("DOMContentLoaded", () => {
    SNTSMainFunction().catch((error) => {
        console.error("SNTS Store Locator failed to initialize", error);
        setMapMessage("Unable to load map.");
    });
});

async function SNTSMainFunction() {
    const mapIconElement = document.getElementById("googleMapIcon");
    const mapIframeElement = document.getElementById("google-map-iframe");

    if (!mapIconElement || !mapIframeElement) {
        return;
    }

    shopUrl = window.Shopify?.shop || "";
    setMapMessage("Loading map...");

    try {
        const locatorSettings = await fetch(`${BACKEND_BASE_URL}/get_locator_settings?shop_url=${encodeURIComponent(shopUrl)}`, {
            method: "GET", mode: "cors", headers: {
                "ngrok-skip-browser-warning": "true",
            },
        });

        if (!locatorSettings.ok) {
            console.warn("Failed to fetch locator settings");
            return;
        }

        const response = await locatorSettings.json();
        window.SNTS_SETTINGS = response.result || {};
    } catch (error) {
        console.error("Error fetching locator settings", error);
        setMapMessage("Unable to load map.");
        return;
    }

    if (!applyThemeSettings(mapIconElement)) {
        setMapMessage("Store locator is disabled.");
        return;
    }

    initializeStoreData();
    attachSearchHandler();
    renderStoresList();
    setupResponsiveStoresList();
    setupLocatorExpandWatcher();
    updateMapIframe();
}

function applyThemeSettings(mapIconElement) {
    const settings = window.SNTS_SETTINGS || {};
    const navStatusActive = settings.nav_status == "1" || settings.nav_status === true;
    const navSupported = settings.nav_support === true || settings.nav_support === "true";

    mapIconElement.style.display = "block";
    const gMapIconElement = document.getElementById("gMapIcon");
    if (settings.nav_icon_url) {
        gMapIconElement.src = settings.nav_icon_url;
    }

    if (settings.nav_location == "2") {
        const isHomePage = window.ShopifyAnalytics?.meta?.page?.pageType === "home";
        if (!isHomePage) {
            mapIconElement.style.display = "none";
            return false;
        }
    }

    if (!(navStatusActive && navSupported)) {
        mapIconElement.style.display = "none";
        return false;
    }

    if (settings.nav_icon_position == "1") {
        iconPosition = "left";
        mapIconElement.style.left = "20px";
        mapIconElement.style.right = "auto";
    } else {
        iconPosition = "right";
        mapIconElement.style.right = "20px";
        mapIconElement.style.left = "auto";
    }

    if (settings.nav_custom_css) {
        const styleElement = document.createElement("style");
        styleElement.type = "text/css";
        styleElement.innerHTML = settings.nav_custom_css;
        document.head.appendChild(styleElement);
    }

    const locatorElement = document.getElementById("effectifyLocator");
    const locatorHeader = document.getElementById("locatorHeader");
    const storesList = document.getElementById("storesListContainer")
    const hideButton = document.getElementById("hideButton");
    const iconOverlayText = document.getElementById("iconOverlayText");
    const storeLocationsHeader = document.getElementById("storeLocationsHeader");
    const searchResultElement = document.getElementById("searchResultsCount");
    const expandButtonElement = document.getElementById("locatorExpandButton");
    const collapseButtonElement = document.getElementById("collapseExpandButton");


    const backgroundColor = getColorSetting(settings.nav_background_color, "f6f6f7");
    const titleColor = getColorSetting(settings.nav_title_color, "1e2433");
    const xButtonColor = getColorSetting(settings.nav_x_button_color, "6d7175");
    const expandButtonColor = getColorSetting(settings.nav_expand_button_color, "6d7175");
    const secondaryColor = getColorSetting(settings.nav_secondary_text_color, "1e2433")

    locatorElement.style.backgroundColor = `#${backgroundColor}`;
    storeLocationsHeader.style.backgroundColor = `#${backgroundColor}`;
    storesList.style.backgroundColor = `#${backgroundColor}`
    locatorHeader.innerText = settings.nav_title || "Store locations";
    locatorHeader.style.color = `#${titleColor}`;
    hideButton.style.stroke = `#${xButtonColor}`;
    searchResultElement.style.color = `#${secondaryColor}`;
    expandButtonElement.style.stroke = `#${expandButtonColor}`
    collapseButtonElement.style.stroke = `#${expandButtonColor}`

    if (settings.nav_icon_text) {
        iconOverlayText.innerText = settings.nav_icon_text;
        iconOverlayText.style.display = "flex";
        if (settings.nav_icon_position == "1") {
            iconOverlayText.style.left = "110%";
            iconOverlayText.style.right = "auto";
            iconOverlayText.style.marginRight = "10px";
            iconOverlayText.style.marginLeft = "0";
        } else {
            iconOverlayText.style.right = "90%";
            iconOverlayText.style.left = "auto";
            iconOverlayText.style.marginLeft = "10px";
            iconOverlayText.style.marginRight = "0";
        }
    }

    return true;
}

function initializeStoreData() {
    const settings = window.SNTS_SETTINGS || {};
    const locations = Array.isArray(settings.store_locations) ? settings.store_locations : [];

    storeLocations = locations.map((store) => ({
        ...store,
        latitude: store.latitude !== undefined ? Number(store.latitude) : undefined,
        longitude: store.longitude !== undefined ? Number(store.longitude) : undefined,
    }));

    storeIndexMap = new Map();
    storeCoordinates = {};

    storeLocations.forEach((store, index) => {
        storeIndexMap.set(store.id, index + 1);
        if (isFinite(store.latitude) && isFinite(store.longitude)) {
            storeCoordinates[store.id] = {
                lat: store.latitude, lng: store.longitude,
            };
        }
    });

    filteredStoreLocations = [...storeLocations];
}

function attachSearchHandler() {
    const searchInput = document.getElementById("storeSearchInput");
    if (!searchInput) return;

    searchInput.addEventListener("input", (event) => {
        updateSearchCount(true);
        const value = (event.target.value || "").trim().toLowerCase();
        const prevSelected = selectedStoreId;

        if (!value) {
            filteredStoreLocations = [...storeLocations];
        } else {
            filteredStoreLocations = storeLocations.filter((store) => {
                const name = (store.name || "").toLowerCase();
                const address = (store.address || "").toLowerCase();
                return name.includes(value) || address.includes(value);
            });
        }

        if (prevSelected && !filteredStoreLocations.some((store) => store.id === prevSelected)) {
            selectedStoreId = null;
        }

        renderStoresList();
        if (value) updateSearchCount();
        updateMapIframe();
    });
}

function renderStoresList() {
    const listElement = document.getElementById("storeLocationsList");
    if (!listElement) return;

    if (filteredStoreLocations.length === 0) {
        listElement.innerHTML = `<div class="store-item" style="border-bottom: none; cursor: default;">
      <p class="store-address font-family" style="margin: 0; color: #6d7175;">No stores found.</p>
    </div>`;
        updateMapIframe();
        return;
    }

    const settings = window.SNTS_SETTINGS || {};
    const titleColor = getColorSetting(settings.nav_title_color, "1e2433");
    const secondaryColor = getColorSetting(settings.nav_secondary_text_color, "6d7175");
    const buttonColor = getColorSetting(settings.nav_button_color, "007BDF");
    const buttonText = settings.nav_button_text || "Get direction";
    const downChevronColor = getColorSetting(settings.nav_down_chevron_color, "6d7175");

    const itemsHtml = filteredStoreLocations
        .map((store) => {
            const storeId = store.id;
            const storeNumber = getStoreNumber(storeId);
            const isSelected = selectedStoreId === storeId;
            const isExpanded = Boolean(isExpandedState[storeId]);
            const hasPhone = Boolean(store.phone);
            const hasImage = Array.isArray(store.image) && store.image.length > 0;
            const hasDetails = hasPhone || hasImage;

            const addressHtml = store.address ? `<div class="store-address-container">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" style="min-width: 20px; height: 20px;">
              <path fill-rule="evenodd" d="M14.25 16h-3.077l.07-.061a17.427 17.427 0 0 0 1.707-1.758c1.224-1.46 2.55-3.574 2.55-5.954 0-3.167-2.328-5.477-5.5-5.477s-5.5 2.31-5.5 5.477c0 2.38 1.326 4.495 2.55 5.954a17.426 17.426 0 0 0 1.708 1.758l.069.061h-3.077a.75.75 0 0 0 0 1.5h8.5a.75.75 0 0 0 0-1.5Zm-4.25-5.5a2 2 0 1 0 0-4 2 2 0 0 0 0 4Z" />
            </svg>
            <p class="store-address font-family" style="color: #${secondaryColor};" id="storeAddress">
              ${escapeHtml(store.address)}
            </p>
          </div>` : "";

            const phoneHtml = hasPhone ? `<div class="phone-section">
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" style="width: 20px; height: 20px;">
                <path fill-rule="evenodd" d="M6.75 4.5c-1.283 0-2.213 1.025-2.044 2.127.384 2.498 1.296 4.459 2.707 5.89 1.41 1.43 3.373 2.389 5.96 2.786 1.101.17 2.126-.76 2.126-2.044v-.727a.25.25 0 0 0-.187-.242l-1.9-.498a.25.25 0 0 0-.182.022l-1.067.576c-.69.373-1.638.492-2.422-.056a8.678 8.678 0 0 1-2.071-2.09c-.542-.787-.423-1.735-.045-2.428l.57-1.047a.252.252 0 0 0 .022-.182l-.498-1.9a.25.25 0 0 0-.242-.187h-.726Zm-3.526 2.355c-.334-2.174 1.497-3.856 3.527-3.855h.726a1.75 1.75 0 0 1 1.693 1.306l.498 1.9c.113.43.058.885-.153 1.276l-.001.002-.572 1.05c-.191.351-.169.668-.036.86a7.184 7.184 0 0 0 1.694 1.71c.187.13.498.156.85-.034l1.067-.576a1.75 1.75 0 0 1 1.276-.153l1.9.498a1.75 1.75 0 0 1 1.306 1.693v.727c0 2.03-1.68 3.86-3.854 3.527-2.838-.436-5.12-1.511-6.8-3.216-1.68-1.703-2.701-3.978-3.121-6.715Z" />
              </svg>
              <a href="tel:${escapeHtml(store.phone)}" class="phone-number font-family" style="color: #${secondaryColor};">
                ${escapeHtml(store.phone)}
              </a>
            </div>` : "";

            const imageUrl = hasImage ? escapeHtml(store.image[0]) : "";
            const imageHtml = hasImage ? `<div class="store-image-section">
              <img src="${imageUrl}" alt="${escapeHtml(store.name)}" class="store-image" />
           </div>` : "";

            const chevronHtml = hasDetails ? `<button class="header-icon-button" onclick="toggleStoreDetails(event, ${storeId})">
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" class="chevron-icon" style="stroke: #${downChevronColor}; transform: ${isExpanded ? "rotate(180deg)" : "rotate(0deg)"};">
                <path fill-rule="evenodd" d="M5.72 8.47a.75.75 0 0 1 1.06 0l3.47 3.47 3.47-3.47a.75.75 0 1 1 1.06 1.06l-4 4a.75.75 0 0 1-1.06 0l-4-4a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" />
              </svg>
           </button>` : "";

            const detailsHtml = hasDetails ? `<div id="store-details-${storeId}" class="store-details" style="display: ${isExpanded ? "block" : "none"};">
              ${phoneHtml}
              ${imageHtml}
           </div>` : "";

            return `<div class="store-item${isSelected ? " selected" : ""}" onclick="handleStoreItemClick(${storeId})" data-store-id="${storeId}">
                <div class="store-header">
                  <div class="store-info">
                    <div class="store-numbered-name">
                      <h3 class="store-name font-family" style="color: #${titleColor};">
                        ${storeNumber}. ${escapeHtml(store.name)}
                      </h3>
                    </div>
                    ${addressHtml}
                  </div>
                  ${chevronHtml}
                </div>
                ${detailsHtml}
                <div class="direction-button-container">
                  <button class="get-direction-button" onclick="handleDirection(event, ${storeId})" style="border-color: #${buttonColor};">
                    <span style="color: #${buttonColor};">${escapeHtml(buttonText)}</span>
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="direction-icon" style="stroke: #${buttonColor}; transform: rotate(315deg); width: 15px;">
                      <path fill-rule="evenodd" d="m5.008 9.61-2.01-4.75c-.354-.838.506-1.676 1.336-1.3l12.163 5.53a1 1 0 0 1 0 1.82l-12.163 5.53c-.83.376-1.69-.462-1.335-1.3l2.01-4.75a1 1 0 0 0 0-.78Zm1.382-.584-1.51-3.57 9.995 4.544-9.995 4.543 1.51-3.569c.03-.074.058-.148.082-.224h3.778a.75.75 0 0 0 0-1.5h-3.778a2.5 2.5 0 0 0-.082-.224Z" clip-rule="evenodd" />
                    </svg>
                  </button>
                </div>
              </div>`;
        })
        .join("");

    listElement.innerHTML = itemsHtml;
}

function updateSearchCount(invisible = false) {
    const countElement = document.getElementById("searchResultsCount");
    if (!countElement) return;
    if (invisible) {
        countElement.innerText = ''    
    } else {
        countElement.innerText = `${window.SNTS_SETTINGS.nav_search_text}: ${filteredStoreLocations.length}`;
    }
}

function handleStoreItemClick(storeId) {
    isExpandedState[storeId] = !isExpandedState[storeId];
    selectedStoreId = selectedStoreId === storeId ? null : storeId;
    renderStoresList();
    updateMapIframe();
}

function toggleStoreDetails(event, storeId) {
    event.stopPropagation();
    isExpandedState[storeId] = !isExpandedState[storeId];
    renderStoresList();
}

function handleDirection(event, storeId) {
    if (event && typeof event.stopPropagation === "function") {
        event.stopPropagation();
    }

    const store = storeLocations.find((location) => location.id === storeId);
    if (!store) return;

    const url = store.url;
    window.open(url, "_blank");

    updateStoreClickCount(storeId);
}

function updateStoreClickCount(storeId) {
    fetch(`${BACKEND_BASE_URL}/update_store_location_click`, {
        method: "POST", headers: {
            "Content-Type": "application/json",
        }, body: JSON.stringify({
            shop_url: shopUrl, store_id: storeId,
        }),
    }).catch((error) => {
        console.warn("Failed to update store click count", error);
    });
}

function hideLocator() {
    const locatorElement = document.getElementById("effectifyLocator");
    if (locatorElement) {
        collapseLocator();
        locatorElement.classList.add("hide");
        document.body.classList.remove("scroll-lock");
        document.documentElement.classList.remove("scroll-lock");
    }
}

function toggleLocator() {
    const locatorElement = document.getElementById("effectifyLocator");
    if (!locatorElement) return;

    if (window.SNTS_SETTINGS.store_locations.length === 1) {
        const storeId = window.SNTS_SETTINGS.store_locations[0]?.id;
        if (storeId) {
            handleDirection(null, storeId);
        }
        return;
    }

    if (locatorElement.classList.contains("hide")) {
        // Show the locator
        locatorElement.classList.remove("hide");
        if (iconPosition === "left") {
            locatorElement.style.left = window.innerWidth > 900 ? "90px" : "60px";
            locatorElement.style.right = "auto";
        } else {
            locatorElement.style.right = window.innerWidth > 900 ? "90px" : "60px";
            locatorElement.style.left = "auto";
        }
        
        // Open in expanded mode on supported (desktop) widths
        setLocatorExpanded(true);
        const hasScroll = document.documentElement.scrollHeight >
                  document.documentElement.clientHeight;
        if (hasScroll) {
            document.documentElement.classList.add("scroll-lock");
        }
    } else {
        // Collapse and then hide
        setLocatorExpanded(false);
        document.documentElement.classList.remove("scroll-lock");
        document.body.classList.remove("scroll-lock");
        locatorElement.classList.add("hide");
    }
}

function setupLocatorExpandWatcher() {
    if (expandDesktopMediaQuery || typeof window.matchMedia !== "function") {
        return;
    }

    expandDesktopMediaQuery = window.matchMedia(`(min-width: ${LOCATOR_EXPAND_MIN_WIDTH}px)`);
    const listener = handleLocatorExpandMediaChange;

    if (typeof expandDesktopMediaQuery.addEventListener === "function") {
        expandDesktopMediaQuery.addEventListener("change", listener);
    } else if (typeof expandDesktopMediaQuery.addListener === "function") {
        expandDesktopMediaQuery.addListener(listener);
    }

    handleLocatorExpandMediaChange(expandDesktopMediaQuery);
}

function expandLocator() {
    const locatorElement = document.getElementById("effectifyLocator");
    if (!locatorElement || locatorElement.classList.contains("hide")) {
        return;
    }

    setLocatorExpanded(!isLocatorExpanded);
}

function collapseLocator() {
    const shouldExpand = false;
    setLocatorExpanded(shouldExpand);
}

function setLocatorExpanded(shouldExpand) {
    const locatorElement = document.getElementById("effectifyLocator");
    const backdropElement = document.getElementById("locatorBackdrop");
    const expandButton = document.getElementById("locatorExpandButton");
    const collapseButton = document.getElementById("collapseExpandButton");

    if (!locatorElement || !backdropElement || !expandButton || !collapseButton) {
        return;
    }

    if (locatorElement.classList.contains("hide") || window.innerWidth < LOCATOR_EXPAND_MIN_WIDTH) {
        shouldExpand = false;
    }

    
    if (shouldExpand) {
        const hasScroll = document.documentElement.scrollHeight >
                  document.documentElement.clientHeight;
        if (hasScroll) {
            document.documentElement.classList.add("scroll-lock");
        }
        locatorElement.classList.add("store-card--expanded");
        backdropElement.classList.add("visible");
        backdropElement.setAttribute("aria-hidden", "false");
        collapseButton.style.display = "block";
        expandButton.style.display = "none";
    } else {
        document.documentElement.classList.remove("scroll-lock");
        document.body.classList.remove("scroll-lock");
        locatorElement.classList.remove("store-card--expanded");
        backdropElement.classList.remove("visible");
        backdropElement.setAttribute("aria-hidden", "true");
        collapseButton.style.display = "none";
        expandButton.style.display = "block";
    }

    isLocatorExpanded = shouldExpand;
    expandButton.setAttribute("aria-pressed", shouldExpand ? "true" : "false");
}

function handleLocatorExpandMediaChange(event) {
    if (!event || typeof event.matches !== "boolean") {
        return;
    }

    if (!event.matches && isLocatorExpanded) {
        collapseLocator();
    }
}

function showMapMessage(message) {
    const mapLoading = document.getElementById("mapLoading");
    if (mapLoading) {
        mapLoading.textContent = message;
        mapLoading.style.display = "flex";
    }
}

function hideMapMessage() {
    const mapLoading = document.getElementById("mapLoading");
    if (mapLoading) {
        mapLoading.style.display = "none";
    }
}

function getStoreNumber(storeId) {
    return storeIndexMap.get(storeId) || 0;
}

function escapeHtml(value) {
    if (value === null || value === undefined) {
        return "";
    }
    return String(value)
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&#39;");
}

function getColorSetting(value, fallback) {
    const color = (value || fallback || "").replace(/[^0-9a-fA-F]/g, "");
    if (color.length === 3 || color.length === 6) {
        return color;
    }
    return fallback;
}

function setupResponsiveStoresList() {
    const listElement = document.getElementById("storesListContainer");
    const toggleButton = document.getElementById("storesToggleButton");

    if (!listElement || !toggleButton) {
        return;
    }

    if (!storesListMediaQuery) {
        storesListMediaQuery = window.matchMedia("(max-width: 768px)");
        const listener = handleStoresMediaChange;
        if (typeof storesListMediaQuery.addEventListener === "function") {
            storesListMediaQuery.addEventListener("change", listener);
        } else if (typeof storesListMediaQuery.addListener === "function") {
            storesListMediaQuery.addListener(listener);
        }
    }

    handleStoresMediaChange();
}

function handleStoresMediaChange() {
    const listElement = document.getElementById("storesListContainer");
    const toggleButton = document.getElementById("storesToggleButton");
    const expandButton = document.getElementById("locatorExpandButton");

    if (!listElement || !toggleButton) {
        return;
    }

    const isMobileView = storesListMediaQuery ? storesListMediaQuery.matches : window.innerWidth <= 768;

    if (isMobileView) {
        expandButton.style.display = "none";
        toggleButton.removeAttribute("hidden");
        if (isStoresListCollapsed) {
            listElement.classList.add("collapsed");
            toggleButton.setAttribute("aria-expanded", "false");
        } else {
            listElement.classList.remove("collapsed");
            toggleButton.setAttribute("aria-expanded", "true");
        }
    } else {
        expandButton.style.display = "block";
        listElement.classList.remove("collapsed");
        toggleButton.setAttribute("aria-expanded", "true");
        toggleButton.setAttribute("hidden", "hidden");
        isStoresListCollapsed = false;
    }
}

function toggleStoresList() {
    const listElement = document.getElementById("storesListContainer");
    const toggleButton = document.getElementById("storesToggleButton");

    if (!listElement || !toggleButton) {
        return;
    }

    const shouldCollapse = !listElement.classList.contains("collapsed");
    if (shouldCollapse) {
        listElement.classList.add("collapsed");
        toggleButton.setAttribute("aria-expanded", "false");
        toggleButton.style.transform = "rotate(180deg)";
    } else {
        listElement.classList.remove("collapsed");
        toggleButton.setAttribute("aria-expanded", "true");
        toggleButton.style.transform = "rotate(0deg)";
    }

    isStoresListCollapsed = shouldCollapse;
}

window.handleStoreItemClick = handleStoreItemClick;
window.toggleStoreDetails = toggleStoreDetails;
window.handleDirection = handleDirection;
window.hideLocator = hideLocator;
window.toggleLocator = toggleLocator;
window.toggleStoresList = toggleStoresList;
window.expandLocator = expandLocator;
window.collapseLocator = collapseLocator;

function updateMapIframe() {
    const iframe = document.getElementById("google-map-iframe");
    if (!iframe) return;

    const storesWithCoordinates = filteredStoreLocations.filter((store) => isFinite(store.latitude) && isFinite(store.longitude));

    if (!shopUrl) {
        setMapMessage("Missing shop information.");
        return;
    }

    if (storesWithCoordinates.length === 0) {
        const message = filteredStoreLocations.length === 0 ? "No stores found." : "No store coordinates available.";
        setMapMessage(message);
        return;
    }

    hideMapMessage();
    iframe.style.display = "block";

    const params = new URLSearchParams();
    params.set("shop_url", shopUrl);
    params.set("store_ids", storesWithCoordinates.map((store) => String(store.id)).join(","));
    if (selectedStoreId) {
        params.set("selected_store_id", String(selectedStoreId));
    }

    const newSrc = `${BACKEND_BASE_URL}/get_map?${params.toString()}`;
    if (iframe.dataset.currentSrc !== newSrc) {
        iframe.dataset.currentSrc = newSrc;
        iframe.src = newSrc;
    }
}

function setMapMessage(message) {
    const iframe = document.getElementById("google-map-iframe");
    const messageElement = document.getElementById("mapIframeMessage");

    if (iframe) {
        iframe.style.display = "none";
        iframe.dataset.currentSrc = "";
        iframe.removeAttribute("src");
    }

    if (messageElement) {
        messageElement.style.display = "flex";
        messageElement.textContent = message;
    }
}

function hideMapMessage() {
    const messageElement = document.getElementById("mapIframeMessage");
    if (messageElement) {
        messageElement.style.display = "none";
        messageElement.textContent = "";
    }
}