/* eslint no-empty: ["error", { "allowEmptyCatch": true }] */
"use strict";
const cm = require("./common.js");


/**
 * Autocomplete of Places (POI). Can be centered on a locaiton or within a bounding box
 * @alias hm:placeAutoSuggest
 * @param opt {Object} options of autosuggest
 * @param opt.search {String} search string
 * @param opt.center {Coord} center search around this coord
 * @param opt.bb {object} - {latm,latM,lngm,lngM}
 * @return  {Promise} Array of {res,title,value,coord}
 */
function placeAutoSuggest(opt) {

    const params = cm.addCredentials({
        q: opt.search
    }, opt);

    if (opt.bb) {
        params.in = opt.bb.lngm + "," + opt.bb.latm + "," + opt.bb.lngM + "," + opt.bb.latM;
        delete params.bb;
    }
    if (opt.center) {
        params.at = opt.center[0] + "," + opt.center[1];
        delete params.center;
    }

    const url = cm.buildUrl("places", "api.here.com/places/v1/autosuggest");
    return cm.hereRest(url, params, "get", false)
        .then(res => {
            let places = res.body.results.filter(place => place.vicinity); // keep only if vicinity field is present

            return places.map(place => {
                return {
                    title: place.title,
                    //value: place.title + ', ' + place.vicinity.replace(/<br\/>/g, ", ") + ' (' + place.category + ')',
                    value: place.title + ", " + place.vicinity.replace(/<br\/>/g, ", "),
                    coord: place.position,
                    res: place,
                };
            });
        });
}


/**
 * Get Categories of Places (POI)
 * @alias hm:placeGetCategory
 * @param {array} center where to search for available categories
 * @return {promise} array of {id,title,icon}
 */
function placeGetCategory(center) {

    if (!center) {
        console.error("placeGetCategory: no center defined");
        return null;
    }
    const params = cm.addCredentials({
        at: center[0] + "," + center[1],
    });

    const url = cm.buildUrl("places", "api.here.com/places/v1/categories/places");
    return cm.hereRest(url, params, "get", false)
        .then(res => {
            let items = res.body.items;
            items.sort(function (a, b) {
                if (a.title > b.title) {
                    return 1;
                }
                if (b.title > a.title) {
                    return -1;
                }
                return 0;
            });
            return items.map(item => {
                return {
                    id: item.id,
                    title: item.title,
                    icon: item.icon
                };
            });
        });

}


/**
 * Search for a Place (POI) around a coordinate matching a name
 * @alias hm:placeSearch
 * @param opt {object} option for search
 * @param opt.at {array} center of search
 * @param opt.q  {text} name to search
 * @param opt.size  {int} number of result to return
 * @param categories  {text} list of comma separated categories for post-filtering
 * @return {promise} array of {id,title,icon}
 */
function placeSearch(opt, categories) {

    if (!opt) {
        console.error("placeSearch: no options defined");
        return null;
    }
    if (!opt.at) {
        console.error("placeSearch: no at defined");
        return null;
    }
    if (!opt.q) {
        console.error("placeSearch: no q defined");
        return null;
    }
    if (opt.at)
        opt.at = opt.at[0] + "," + opt.at[1];

    var settings = {
        size: 100
    };
    const params = cm.addCredentials(settings, opt);

    const url = cm.buildUrl("places", "api.here.com/places/v1/discover/search");
    return cm.hereRest(url, params, "get", false)
        .then(res => {
            let items = res.body.results.items;

            if (categories) {
                return items.filter(function (item) {
                    let cat = item.category.id;
                    return categories.includes(cat);
                });
            } else
                return items;
        });

}



/**
 * Discover places (POI) around a coordnate belonging to a list of categories
 * @alias hm:placeExplore
 * @param opt {object} option for search
 * @param opt.at {array} center of search
 * @param opt.size  {int} number of result to return
 * @param categories  {text} list of comma separated categories for post-filtering
 * @return {array} array of {id,title,icon}
 */
function placeExplore(opt, categories) {

    if (!opt) {
        console.error("placeExplore: no options defined");
        return null;
    }
    if (!opt.at) {
        console.error("placeExplore: no at defined");
        return null;
    }

    if (opt.at)
        opt.at = opt.at[0] + "," + opt.at[1];

    var settings = {
        size: 100
    };
    // for explore, can be put in parameters of request
    if (categories) opt.cat = categories;

    const params = cm.addCredentials(settings, opt);

    const url = cm.buildUrl("places", "api.here.com/places/v1/discover/explore");
    return cm.hereRest(url, params, "get", false)
        .then(res => {
            let items = res.body.results.items;

            return items;
        });

}


module.exports = {
    placeAutoSuggest: placeAutoSuggest,
    placeGetCategory: placeGetCategory,
    placeSearch: placeSearch,
    placeExplore: placeExplore
};