﻿Widgets.ListingSearch = function (options = null) {
    let rawData = null;
    this.className = "defaultListingSearchContainer";
    this.currentDisplay = null;
    this.currentScrollId = null;
    Widgets.BaseWidget.call(this, "/Widgets/ListingSearch/ListingSearch", this.className);

    //custom overriding options
    BaseHelper.MergeIntoObject(this, options);

    this._setup = function () {
        Widgets.BaseWidget.prototype._setup.call(this);
        this.isRefreshing = false;
        this.pBar = new PaginationBar(0, 3);
        this.pBar.init();
        this.defaultImageUrl = "/img/no-housephoto.jpg"
        this.fetchCount = 50;
        this.pendingRawDataList = [];

        this.dataTask = null;
        this.currentUuid = null;

        this.currentData = null;
        this.prevListingRequest = {
            request: null,
            response:null
        }
        this.prevMapRequest = {
            requst: null,
            response:null
        }
    };

    this.getLoadData = async function () {
        let result = Widgets.BaseWidget.prototype.getLoadData.call(this);

        let json_response = await BaseHelper.MakeAJAXGetRequest("/api/Website/IsListHubSite");
        let response = JSON.parse(json_response);
        this.IsListHub = response["IsListHub"];
        //console.log("this.IsListHub", this.IsListHub);

        this.ListingSearchItemMarkup = await BaseHelper.MakeAJAXGetRequest("/Widgets/ListingSearch/ListingSearchItem");
        this.ListingSearchFillerItemMarkup = await BaseHelper.MakeAJAXGetRequest("/Widgets/ListingSearch/ListingSearchFillerItem");
        return result;
    };

    this.getRawData = async () => {
        return new Promise((resolve, reject) => {
            if (this.rawData != null) {
                resolve(this.rawData);
            }
            if (this.isRefreshing) {
                this.pendingRawDataList.push((rawData) => {
                    resolve(rawData);
                });
            }
            else {
                resolve(this.rawData);
            }
        });
    };

    // Returns a populated div.
    this.GetPopulatedCard = function (data, heartKey) {
        let div = document.createElement("div");

        div.innerHTML = this.ListingSearchItemMarkup;

        this.populateSearchListingItem(div, data, true, heartKey);

        div.firstChild.attributes["data-listingid"].value = data.ListingID;

        return div.firstChild;
    };

    //returns a card to use as a filler while loading.
    this.GetFillerCard = function () {
        let div = document.createElement("div");
        div.innerHTML = this.ListingSearchFillerItemMarkup;
        return div.firstChild;
    }

    this.setFilters = (filterArr) => {
        if (this.currentData == null) {
            this.currentData = this.getDefaultData();
        }
        this.currentData.page = 0;
        this.currentData.data = null;
        let sortFilter = null;
        for (let i = 0; i < filterArr.length; i++) {
            let f = filterArr[i];
            if (f.name == "SortResult") {
                sortFilter = f;
                break;
            }
        }
        if (sortFilter == null) {
            this.currentData.orderBy = "ListingDate";
            this.currentData.orderSort = "DESC";
        }
        else {
            let sfValue = sortFilter.value;
            if (sfValue == "lowest") {
                this.currentData.orderBy = "ListPrice";
                this.currentData.orderSort = "ASC";
            }
            else if (sfValue == "highest") {
                this.currentData.orderBy = "ListPrice";
                this.currentData.orderSort = "DESC";
            }
            else if (sfValue == "lotsize") {
                this.currentData.orderBy = "LotSize";
                this.currentData.orderSort = "DESC";
            }
            else if (sfValue == "openhouse") {
                this.currentData.orderBy = "OpenHouseUpcomingStartDate";
                this.currentData.orderSort = "ASC";
            }
            else {
                this.currentData.orderBy = "ListingDate";
                this.currentData.orderSort = "DESC";
            }
        }
        this.currentData.filterArr = filterArr;
    };

    this.setMapRequest = (request) => {
        if (this.currentData == null) {
            this.currentData = this.getDefaultData();
        }
        this.currentData.page = 0;
        this.currentData.data = null;
        this.currentData.mapRequest = request;
    };


    this.getDefaultData = () => {
        let data = {
            filterArr: null,
            page: 0,
            fetch: this.fetchCount,
            orderBy: "ListingDate",
            orderSort: "DESC",
            isMap: false,
            data: null
        }
        return data;
    };

    this.getMaxPage = (maxPage) => {
        return maxPage;
    };

    this.populateGrid = (listings) => {
        this.clearGrid();
        if (this.currentData == null || listings == null) {
            return;
        }
        this.currentData.data = listings;
        let pData = listings.PaginatedData;
        let currentPage = pData.offset / pData.fetch;
        this.pBar.currentPage = currentPage;
        let maxPage = this.getMaxPage(pData.maxPages);
        this.pBar.setMaxPage(maxPage);
        this.pBar.refresh();
        this.currentPropTypeList = this.getCurrentPropTypeList();
        if (BaseHelper.isNullOrUndefined(this.ListingIDLookupHeart)) {
            this.ListingIDLookupHeart = {};
        }
        else {
            for (let key in this.ListingIDLookupHeart) {
                delete this.ListingIDLookupHeart[key]["ListingSearch"];
            }
        }
        if (pData != null && pData.data != null) {
            pData.data.forEach((record) => {
                let div = this.GetPopulatedCard(record, "ListingSearch");
                this.ListingSearchItemContainer.appendChild(div);

                //remove the background src before appending to element and add the unveil src to element
                let imgTop = div.querySelector(".card-img-top");
                let src = imgTop.getAttribute("image-src");
                //imgTop.setAttribute("data-src", src);
                //imgTop.setAttribute("data-lazyload", false);
                //imgTop.removeAttribute("style");

                imgTop.setAttribute("style", "background-image:url('" + src + "'),url('/img/no-housephoto.jpg');");
            });
        }

        window.addEventListener("scroll", () => {
            this.onScroll();
        });
    };

    this.onScroll = () => {
        let scrollId = this.currentScrollId = BaseHelper.getUuid();
        //console.log("scroll");
        //window.setTimeout(() => {
        //    if (this.currentScrollId == scrollId) {
        //        let imgList = this.ListingSearchItemContainer.querySelectorAll(".card-img-top[data-lazyload=false]");
        //        for (let i = 0; i < imgList.length; i++) {
        //            let img = imgList[i];
        //            let windowSides = BaseHelper.getWindowSides()
        //            let boundSides = BaseHelper.getBoundSides(img.getBoundingClientRect())
        //            if (BaseHelper.isScrolledIntoViewSides(windowSides, boundSides)) {
        //                let src = img.getAttribute("image-src");
        //                img.setAttribute("style", "background-image:url('" + src + "'),url('/img/no-housephoto.jpg');");
        //                img.setAttribute("data-lazyload", true);
        //            }
        //        }
        //    }
        //}, 200);
    };

   

    //this.clearSavedListings = () => {
    //  if (
    //    this.currentData == null ||
    //    this.currentData.data == null ||
    //    this.currentData.data.PaginatedData == null ||
    //    this.currentData.data.PaginatedData.data == null) {
    //    return;
    //  }
    //  let data = this.currentData.data.PaginatedData.data;
    //  data.forEach((d) => {
    //    d.SiteUserSavedListingStatusTblID = null;
    //  })
    //  this.populateGrid(this.currentData.data);
    //};

    this.getValueOrEmpty = (str) => {
        if (str == null) {
            return "";
        }
        else {
            return str;
        }
    };

    this.getUrlAddress = (record) => {
        let streetNumber = record["StreetNumber"];
        let streetName = record["StreetName"];
        let unitNumber = record["UnitNumber"];
        let city = record["City"];
        let state = record["State"];
        let zip = record["Zip"];
        let fullAddress = this.getValueOrEmpty(streetNumber) + " " + this.getValueOrEmpty(streetName) + " " + this.getValueOrEmpty(unitNumber) + " " + this.getValueOrEmpty(city) + " " + this.getValueOrEmpty(state) + " " + this.getValueOrEmpty(zip);
        //replace special characters with space
        fullAddress = fullAddress.replaceAll(/[^A-Za-z0-9]/g, "");
        //replace multiple spaces with single space
        fullAddress = fullAddress.replaceAll(/\s+/g, ' ');
        fullAddress = fullAddress.trim();
        //replace all spaces with underscore
        fullAddress = fullAddress.replaceAll(' ', '_');
        return fullAddress;
    };

    this.getCurrentPropTypeList = () => {
        if (this.currentData == null || this.currentData.filterArr == null || this.currentData.filterArr.length == null) {
            return null;
        }
        let filterArr = this.currentData.filterArr;
        for (let i = 0; i < filterArr.length; i++) {
            f = filterArr[i];
            if (f.name == "PropTypeList") {
                return f.value;
            }
        }
        return null;
    };

    this.isNewlyListed = function (record) {
        if (record == null || record.ListingDate == null) {
            return false;
        }
        let dtListing = new Date(record.ListingDate);
        if (isNaN(dtListing)) {
            return false;
        }
        let now = new Date();
        let dayDiff = (now - dtListing) / (1000 * 3600 * 24);
        if (dayDiff <= 7) {
            return true;
        }
        return false;
    };


    this.isNewConstruction = function (record) {
        if (record == null || record.PropType8 == null) {
            return false;
        }
        if (record.PropType8 == 1) {
            return true;
        }
        return false;
    };

    this.isComingSoon = function (record) {
        if (record == null || record.ListingStatusTblID == null) {
            return false;
        }
        if (record.ListingStatusTblID == 4) {
            return true;
        }
        return false;
    };


    this.getOpenHouseDate = function (record) {
        if (record == null) {
            return null;
        }
        let tzOffset = parseInt(record.TimeZone);
        let timezone = null;
        let dtOpenHouse = new Date(record.OpenHouseUpcomingStartDate);
        if (isNaN(dtOpenHouse) || dtOpenHouse.getFullYear() == 5000) {
            return null;
        }

        if (record.LocalOpenHouseUpcomingStartDate != null && record.DayLightSaving != null && !isNaN(tzOffset)) {
            if (tzOffset == 6) {
                timezone = "Central";
            }
            else if (tzOffset == 7) {
                timezone = "Mountain";
            }
            else if (tzOffset == 8) {
                timezone = "Pacific";
            }
            else if (tzOffset == 9) {
                timezone = "Alaskan";
            }
            dtOpenHouse = new Date(record.OpenHouseUpcomingStartDate);
        }

        return {
            dtOpenHouse: dtOpenHouse,
            timezone: timezone
        }
    };

    this.SetSavedListing = async function (ListingID, save) {
        let data = {
            ListingID: ListingID,
            Save: save == true ? 1 : 0
        };
        let json_response = await BaseHelper.MakeAJAXPostJSONRequest("/api/SiteUser/SetSiteUserListing", data, false);
        let response = JSON.parse(json_response);
        //console.log(response);
        if (response.Status == 1) {
            let hItemObj = this.ListingIDLookupHeart[ListingID];
            if (hItemObj != null) {
                for (let key in hItemObj) {
                    heartItem = hItemObj[key];
                    if (save == true) {
                        this.ToggleHeart(heartItem, true);
                    }
                    else {
                        this.ToggleHeart(heartItem, false);
                    }
                }
            }
        }
        else {
            this.PendingSavedListingID = ListingID;
        }
        if (this.onSavedListingComplete != null) {
            this.onSavedListingComplete(this, response);
        }
    };

    this.onSavedListingComplete = null;

    this.clearHearts = function () {
        for (let key in this.ListingIDLookupHeart) {
            let hItemObj = this.ListingIDLookupHeart[key];
            if (hItemObj != null) {
                for (let hiKey in hItemObj) {
                    hItem = hItemObj[hiKey];
                    this.ToggleHeart(hItem, false);
                }
            }
        }
    };

    this.populateHearts = function (data) {
        this.clearHearts();
        if (data != null && data.length > 0) {
            data.forEach((savedListing) => {
                let hItemObj = this.ListingIDLookupHeart[savedListing.ListingID];
                if (hItemObj != null) {
                    for (let key in hItemObj) {
                        heart = hItemObj[key];
                        this.ToggleHeart(heart, true);
                    }
                }
            })
        }
    };

    this.ToggleHeart = function (heartItem, saved) {
        let heartPath = heartItem.path;
        heartItem.heart.setAttribute("data-saved", saved == true ? 1 : 0);
        if (saved) {
            heartPath.setAttribute("stroke", "#FFF")
            heartPath.setAttribute("fill-opacity", 1)
            heartPath.setAttribute("fill", "#F00")
        }
        else {
            heartPath.setAttribute("stroke", "#FFF")
            heartPath.setAttribute("fill-opacity", 0.2)
            heartPath.setAttribute("fill", "#000")
        }
    };

    this.getListingName = (data) => {
        let result = data.ListingStatusName;
        if (data.ListingStatusCategoryTypeTblID == 2) {
            if (data.ListingStatusCategoryFullName != null) {
                result = data.ListingStatusCategoryFullName;
            }
        }
        return result;
    };

    this.getListingColor = (data) => {
        let result = data.ListingStatusCategoryColor;
        if (data.ListingStatusTblID == 4 || result == null) {
            result = data.ListingStatusColor;
        }
        return result;
    };

    // Populates a ListingSearchItem with listing data.
    this.populateSearchListingItem = (siContainer, record, canOpenInNewWindow, heartKey) => {
        try {
            let box = siContainer.querySelector("a.box");
            box.href = "/prop-details/" + record.ListingID + "/" + this.getUrlAddress(record);
            //box.setAttribute("class", "img");
            if (canOpenInNewWindow != undefined && canOpenInNewWindow == true) {
                box.setAttribute("target", "_blank");
            }

            let spanSearchResultPrice = siContainer.querySelector(".search-result-price");
            let spanSearchResultAddress = siContainer.querySelector(".srAddress");
            let liSearchResultBedrooms = siContainer.querySelector(".search-result-bedrooms");
            let liSearchResultBathrooms = siContainer.querySelector(".search-result-bathrooms");
            let liSearchResultSqft = siContainer.querySelector(".search-result-sqft");
            let liSearchResultAcres = siContainer.querySelector(".search-result-lot");
            let spanSearchResultCityStateZip = siContainer.querySelector(".srCity");
            let spanSearchResultPropType = siContainer.querySelector(".search-result-proptype");
            let propSaleStatus = siContainer.querySelector(".propSaleStatus");
            let propSaleStatusText = siContainer.querySelector(".propSaleStatus span");
            let spanNewlyListed = siContainer.querySelector("span.NewlyListed");
            let spanComingSoon = siContainer.querySelector("span.ComingSoon");
            let spanNewConstruction = siContainer.querySelector("span.NewConstruction");
            let spanOpenHouseDate = siContainer.querySelector("span.OpenHouseDate");
            let spanOpenHouseDateText = siContainer.querySelector("span.OpenHouseDate span");
            let divCardImageTop = siContainer.querySelector("div.card-img-top");
            let heartContainer = siContainer.querySelector(".heart-container");
            let svgHeart = siContainer.querySelector(".heart-container .svgHeart");
            let svgHeartPath = siContainer.querySelector(".heart-container .svgHeart path");
            let divOfficeName = siContainer.querySelector(".card-body .officeName");
            if (record["IdxFeedTypeID"] == 71 || record["IdxFeedTypeID"] == 72) {
                let officeName = record["OfficeName"];
                if (officeName != null) {
                    officeName = officeName.toUpperCase();
                }
                divOfficeName.innerText = officeName;
            }

            let heartItem = {
                "record": record,
                "heartContainer": heartContainer,
                "heart": svgHeart,
                "path": svgHeartPath
            };

            if (this.ListingIDLookupHeart != null) {
                if (this.ListingIDLookupHeart[record.ListingID] == null) {
                    this.ListingIDLookupHeart[record.ListingID] = {};
                }
                this.ListingIDLookupHeart[record.ListingID][heartKey] = heartItem;
                if (record.SiteUserSavedListingStatusTblID == 1) {
                    this.ToggleHeart(heartItem, true);
                }
                else {
                    this.ToggleHeart(heartItem, false);
                }
            }

            heartContainer.addEventListener("click", (e) => {
                let saved = heartItem.heart.getAttribute("data-saved");
                if (saved == 1) {
                    saved = false;
                    this.SetSavedListing(record.ListingID, false)
                }
                else {
                    saved = true;
                    this.SetSavedListing(record.ListingID, true)
                }
            });

            let imgfeedLogo = siContainer.querySelector(".feedLogo");
            if (this.isComingSoon(record)) {
                spanComingSoon.style.display = "inline-block";
            }
            else if (this.isNewlyListed(record)) {
                spanNewlyListed.style.display = "inline-block";
            }
            else if (this.isNewConstruction(record)) {
                spanNewConstruction.style.display = "inline-block";
            }

            let openHouseDate = this.getOpenHouseDate(record);
            if (openHouseDate != null && openHouseDate.dtOpenHouse != null) {
                spanOpenHouseDate.style.display = "inline-block";
                let dtOh = openHouseDate.dtOpenHouse;
                spanOpenHouseDateText.innerText = (dtOh.getMonth() + 1) + "/" + dtOh.getDate()
            }
            let streetAddress = "";
            if (BaseHelper.displayAddress(record)) {
                let addressParts = [];
                addressParts.push(record["StreetNumber"]);
                addressParts.push(record["StreetDirPrefix"]);

                let streetName = record["StreetName"];
                let streetSuffix = record["StreetSuffix"];

                addressParts.push(streetName);
                if (streetName == null) {
                    addressParts.push(streetSuffix);
                }
                else if (
                    streetSuffix
                    && !streetName.toUpperCase().endsWith(streetSuffix.toUpperCase())
                ) {
                    addressParts.push(streetSuffix);
                }
                addressParts.push(record["StreetDirSuffix"]);
                addressParts.push(record["UnitNumber"]);
                let filteredAddress = addressParts.filter(part => part);
                streetAddress = BaseHelper.toTitleCase(filteredAddress.join(" "));
                if (record["StreetNumber"] == null && record["StreetName"] == null && record["AddressLine"] != null) {
                    streetAddress = BaseHelper.toTitleCase(record["AddressLine"].split(',')[0]);
                }
            }
            let listPrice = record.SortPrice == null ? "" : BaseHelper.dollarFormatter.format(record.SortPrice);
            let houseSize = "--";
            let lotSize = "--";
            houseSize = BaseHelper.getHouseSize(record);
            lotSize = BaseHelper.getLotSize(record);
            let CityStateZip = BaseHelper.toTitleCase(this.getValueOrEmpty(record.City)) + ", " + this.getValueOrEmpty(record.State) + ", " + BaseHelper.toTitleCase(this.getValueOrEmpty(record.Zip));
            let bedroomCount = "--";
            if (record.BedroomCount != null && record.BedroomCount != 0) {
                bedroomCount = record.BedroomCount
            }
            let bathroomCount = "--";
            if (record.BathroomCount != null && record.BathroomCount != 0) {
                bathroomCount = record.BathroomCount
            }
            let housePhotoUrl;
            if (canOpenInNewWindow) {
                housePhotoUrl = "/api/listing/" + record.ListingID + "/mainphoto";
            }
            else {
                housePhotoUrl = this.getHousePhotoUrl(record);
            }
            BaseHelper.setBackgroundImageWithFallback(divCardImageTop, housePhotoUrl,"/images/photos-coming-soon.svg", "/img/no-housephoto.jpg");
            //divCardImageTop.style = "background-image: url('" + housePhotoUrl + "'), url('/img/no-housephoto.jpg');";
            divCardImageTop.setAttribute("image-src", housePhotoUrl);
            divCardImageTop.setAttribute("role", "img");
            divCardImageTop.setAttribute("aria-label", "Photo for " + streetAddress + ", " + CityStateZip);
            spanSearchResultPrice.innerText = listPrice
            spanSearchResultAddress.innerText = streetAddress.trim();
            liSearchResultBedrooms.prepend(bedroomCount + " ");
            liSearchResultBathrooms.prepend(bathroomCount + " ");
            liSearchResultSqft.innerText = houseSize;
            liSearchResultAcres.innerText = lotSize;
            spanSearchResultCityStateZip.innerText = CityStateZip;
            spanSearchResultPropType.innerText = this.getValueOrEmpty(record.PropertyTypeName);
            let color = this.getListingColor(record);
            let name = this.getListingName(record);
            propSaleStatus.style.color = this.getValueOrEmpty(color);
            propSaleStatusText.innerText = this.getValueOrEmpty(name);

            if (record["IdxFeedLogoImagePath"] == null) {
                imgfeedLogo.style.display = "none";
            }
            else {
                imgfeedLogo.src = record["IdxFeedLogoImagePath"];
                imgfeedLogo.style.display = "block";
                imgfeedLogo.setAttribute("alt", record.ListingMlsName);
            }
        }
        catch (e) {
            console.log(e);
        }
    };

    this.getHousePhotoUrl = (record) => {
        let providerID = record.IdxFeedProviderID;

        //trestle
        if (providerID != 1 && providerID != 4) {
            let result = record.ListingMediaPreferredUrl;

            if (result == null) {
                result = record.ListingMediaFirstUrl;
            }

            if (result == null) {
                return this.defaultImageUrl
            }

            return result;
        }

        //mlsgrid
        let url = record.FirstPhotoURL;
        let key = record.FirstMediaKey;
        let type = record.FirstMediaType;
        let origin = record.OriginatingSystemName
        if (this.currentData == null || this.currentData.data == null || this.currentData.data.AzureStorageBaseUrl == null || providerID == null || BaseHelper.isStringNullOrWhiteSpace(url) || BaseHelper.isStringNullOrWhiteSpace(key)) {
            return this.defaultImageUrl;
        }

        let base = this.currentData.data.AzureStorageBaseUrl + "/images/";

        if (providerID == 1) {
            let provider = null;
            provider = "MlsGrid/";
            let parts = url.split('/');
            let fileName = parts[parts.length - 1];
            let result = base + provider + key + "-" + fileName;
            return result;
        }
        else if (providerID == 4) {
            let provider = null;
            provider = "MetroList2022/";
            let result = base + provider + origin.replaceAll(' ', '_') + "-" + record.ListingKey + "-" + key
            return result;
        }
        else {
            return this.defaultImageUrl
        }
    };

    this.clearGrid = (listings) => {
        this.ListingSearchItemContainer.innerHTML = "";
    };
        this.findListings = async (request) => {
        let response = await BaseHelper.MakeAJAXPostJSONRequest("/api/Listing/FindListings", request);
        return response;
    };
    //-------------------------------------------------------------------------------------------------
    this.getListingRequest = (filterArr, page, fetch, orderBy, orderSort, count) => {
        let data =
        {
            filterArr: filterArr,
            page: page,
            fetch: fetch,
            orderBy: orderBy,
            orderSort: orderSort,
            count: count
        };
        if (data.filterArr == null) {
            data.filterArr = this.currentData.filterArr;
        }
        return JSON.parse(JSON.stringify(data));
    };

    this.makeListingRequest = () => {
        let page = this.pBar.currentPage
        let data = this.currentData;
        let count = -1;
        if (this.currentData.data != null && this.currentData.data.PaginatedData != null) {
            count = this.currentData.data.PaginatedData.count
        }
        let request = this.getListingRequest(data.filterArr, page, data.fetch, data.orderBy, data.orderSort, count);
        return request;
    }

    this.findListings = async (request) => {
        let response = await BaseHelper.MakeAJAXPostJSONRequest("/api/Listing/FindListings", request);
        return response;
    };

    this.getListingData = async (request) => {
        if (this.currentData == null || this.currentData.filterArr == null) {
            return;
        }
        let response = await this.findListings(request);
        if (this.IsListHub) {
            let listHubResponse = JSON.parse(response);
            const listingKeyArray = [];
            listHubResponse.PaginatedData.data.forEach((d) => {
                listingKeyArray.push('{key:\'' + d.ListingKey + '\'}');
            })
            let listHubListingKeys = listingKeyArray.join(", ");
            //console.log("listHubListingKeys", listHubListingKeys);
            lh('submit', 'SEARCH_DISPLAY', '[' + listHubListingKeys + ']');
        }
        return {
            request: request,
            response: response
        };
    };
    //-------------------------------------------------------------------------------------------------
    this.getAreaRequest = (mapRequest, page) => {
        let request = JSON.parse(JSON.stringify(mapRequest));
        request.page = page;
        return request;
    };

    this.makeAreaRequest = () => {
        return this.getAreaRequest(this.currentData.mapRequest, this.pBar.currentPage);
    }

    this.getArea = async (request) => {
        let response = await $.post("/api/Listing/listingSearcharea", request);
        return response;
    };

    this.getMapData = async (request) => {
        if (this.currentData == null || this.currentData.mapRequest == null) {
            return;
        }
        let response = await this.getArea(request);
        if (this.IsListHub) {
            let listHubResponse = JSON.parse(response);
            const listingKeyArray = [];
            listHubResponse.PaginatedData.data.forEach((d) => {
                listingKeyArray.push('{key:\'' + d.ListingKey + '\'}');
            })
            let listHubListingKeys = listingKeyArray.join(", ");
            //console.log("listHubListingKeys", listHubListingKeys);

            lh('submit', 'SEARCH_DISPLAY', '[' + listHubListingKeys + ']');
        }
        return {
            request: request,
            response: response
        };
    };
    //--------------------------------------------------------------------------------------------
    this.getKeywordData = async () => {
        if (this.currentData == null || this.currentData.filterArr == null) {
            return;
        }
        let data = this.currentData;
        let response = await this.getSearchKeywords(data.filterArr);
        return response;
    };

    this.isNewRequest = async () => {
        if (this.currentData?.mapRequest != null) {
            result = await this.getMapData();
        }
        else if (this.currentData?.filterArr != null) {
            result = await this.getListingData();
        }
        return true;
    };

    this.getData = async (request) => {
        let result = null;
        
        if (this.currentData?.mapRequest != null) {
            result = await this.getMapData(request);
        }
        else if (this.currentData?.filterArr != null) {
            result = await this.getListingData(request);
        }
        return result;
    };

    this.getRequest = () => {
        let result = null;
        if (this.currentData?.mapRequest != null) {
            result = this.makeAreaRequest();
        }
        else if (this.currentData?.filterArr != null) {
            result = this.makeListingRequest();
        }
        return result;
    };

    this.hasRequestChanged = async () => {
        let result = null;
        if (this.currentData?.mapRequest != null) {
            result = await this.getMapData(this.pBar.currentPage);
        }
        else if (this.currentData?.filterArr != null) {
            result = await this.getListingData(this.pBar.currentPage);
        }
        return result;
    };

    this.refresh = async () => {
        if (this.currentData == null) {
            return null;
        }
        this.isRefreshing = true;
        //give the latest call of refresh a unique id
        let uuid = this.currentUuid = BaseHelper.getUuid() 
        //-----------------------------------------------------------------
        //store the request, if it was previously retrieved, then just reuse it.
        let request = this.getRequest();
        if (this.prevRequest != null && JSON.stringify(this.prevRequest) == JSON.stringify(request)) {
            return {
                type: "current",
                data: this.rawData
            };
        }
        //-----------------------------------------------------------------
        this.ToggleLoading(true); //display loading circle
        let dataTask = this.dataTask = this.getData(request); //get the needed to refresh the display
        let result = await this.dataTask; //wait for the data to come in.
        
        while (this.dataTask != dataTask) { 
            //if refresh called again before the data was retrieved, await the latest task
            dataTask = this.dataTask;
            result = await dataTask;
        }

        //check if the current instance is the latest refresh call.
        //if it wasnt, just return the data without refreshing the page.
        if (this.currentUuid != uuid) {
            return {
                type: "copy",
                data: this.rawData
            };
        }

        //if current instance is the latest refresh call, refresh the page.
        //only need to refresh the page once with the latest data.
        let response = result.response;
        this.rawData = JSON.parse(response);
        this.isRefreshing = false;
        this.ToggleLoading(false);
        //-----------------------------------------------------------------
        this.populateGrid(this.rawData);
        this.prevRequest = request;
        this.pendingRawDataList.forEach((pendingRawData) => {
            pendingRawData(this.rawData);
        });
        this.pendingRawDataList = [];
        if (this.onRefreshComplete != null) {
            this.onRefreshComplete(this);
        }
        this.onScroll();
        return {
            type: "latest",
            data: this.rawData
        };
    };

    this.onRefreshComplete = null;

    this.getSearchKeywords = async (filterArr) => {
        let data =
        {
            filterArr: filterArr,
        };

        if (data.filterArr == null) {
            data.filterArr = this.currentData.filterArr;
        }

        let result = await BaseHelper.MakeAJAXPostJSONRequest("/api/Listing/GetSearchKeywords", data);

        return result;
    };

    this.onTemplateLoad = function () {
        this.ListingSearchItemContainer = this.element.querySelector(".ListingSearchItemContainer")        
        this.ListingSearchPagination = this.element.querySelector(".ListingSearchPagination");
        //-------------------------------------------------------------------------
        //Update loading screen
        this.fillerContainer = document.createElement("div");
        this.ListingSearchFillerContainer = document.createElement("div");

        this.fillerContainer.setAttribute("class", "container");
        this.ListingSearchFillerContainer.setAttribute("class", "ListingSearchFillerContainer row row-cols-1 row-cols-sm-2 row-cols-lg-3 g-3");

        this.fillerContainer.appendChild(this.ListingSearchFillerContainer);

        this.div_loading.innerHTML = "";
        this.div_loading.appendChild(this.fillerContainer);
        //-------------------------------------------------------------------------
        this.ListingSearchPagination.appendChild(this.pBar.element);

        for (let i = 0; i < 20; i++) {
            let div = this.GetFillerCard();
            this.ListingSearchFillerContainer.appendChild(div);
        }
        this.pBar.onChange = (e) => {
            if (this.currentData != null) {
                //refresh and display new page if the current page is different than the page in pBar
                if (this.currentData.page != this.pBar.currentPage) {
                    this.currentData.page = this.pBar.currentPage;
                    this.refresh();
                }
            }
        }
        //this.btnPrevPage.addEventListener("click", this.onPrevPage);
        //this.btnNextPage.addEventListener("click", this.onNextPage);
    };


    this.changePage = (diff) => {
        if (this.currentData == null) {
            return
        }
        this.setPage(this.currentData.page + 1);
    };

    this.setPage = (page) => {
        this.currentData.page = page;
        if (this.currentData == null || this.currentData.data == null || this.currentData.data.PaginatedData == null) {
            return
        }
        let pData = this.currentData.data.PaginatedData;
        if (this.currentData.page < 0) {
            this.currentData.page = 0;
        }
        if (this.currentData.page >= pData.maxPages) {
            this.currentData.page = pData.maxPages - 1;
        }
    };
}
Widgets.ListingSearch.prototype = new Widgets.ListingSearch();
