import { convertToJavaLocale } from './helpers';

const SEARCH_QUERY_KEY = 'q';
const SORT_QUERY_KEY = 'order';
const PAGE_QUERY_KEY = 'page';
const LOCALE_KEY = 'locale';
const PRODUCTLINE_QUERY_KEY = 'pl';
const COMPARE_QUERY_KEY = 'productId';

/**
* Casts param to Number if it is numeric, leave unchanged if not
* @param {any} val
* @returns {any}
*/
function castToNumberIfNumeric(val) {
    // eslint-disable-next-line no-restricted-globals
    return !isNaN(val) ? Number(val) : val;
}

/**
 * Parses a search querystring to an object
 * @param {string} search, defaults to window.location.search
 * @returns {object} the objectified querystring
 */
export function getUrlParams(search = window.location.search) {
    if (!search) {
        return {};
    }
    const hashes = search.slice(search.indexOf('?') + 1).split('&');
    return hashes.reduce((params, hash) => {
        const newParams = { ...params };
        const [queryKey, queryVal] = hash.split('=');
        const typedVal = castToNumberIfNumeric(decodeURIComponent(queryVal));
        if (newParams[queryKey]) {
            newParams[queryKey] = [...newParams[queryKey], typedVal];
        } else {
            newParams[queryKey] = [typedVal];
        }
        return newParams;
    }, {});
}

function getQueryParams() {
    const urlParams = window.location.search.split('&');
    if (urlParams.length) {
        const firstQuery = urlParams[0].replace('?', '');
        urlParams.splice(0, 1, firstQuery);
    }
    return urlParams;
}

function getDefaultListingQueryParams(defaultQueryKeys) {
    const urlParams = window.location.search.split('&');
    if (urlParams.length) {
        const firstQuery = urlParams[0].replace('?', '');
        urlParams.splice(0, 1, firstQuery);
    }
    const filteredUrlParams = urlParams.filter(urlParam => {
        const [queryKey] = urlParam.split('=');
        if (defaultQueryKeys.includes(queryKey)) {
            return true;
        }
        return false;
    });
    return filteredUrlParams;
}

export function replaceUrlParam(queryKey, newId, prevId) {
    const baseUrl = window.location.pathname;
    const urlParams = getQueryParams();

    const prevUrlParam = `${queryKey}=${prevId}`;
    const indexOfPrevUrlParam = urlParams.indexOf(prevUrlParam);

    if (indexOfPrevUrlParam !== -1) {
        urlParams.splice(indexOfPrevUrlParam, 1);
    }

    const newUrlParam = `${queryKey}=${newId}`;
    urlParams.push(newUrlParam);

    const updatedUrl = `${baseUrl}?${urlParams.join('&')}`;
    window.history.pushState(null, null, updatedUrl);
}

// when parameters change, push the history for the page's query to reflect what was fetched through ajax
export function updatePageUrl(query) {
    const baseUrl = window.location.pathname;
    const newStateUrl = `${baseUrl}?${query}`;
    window.history.pushState(null, null, newStateUrl);
}

// get the AJAX endpoint to fetch list of a query
export function getListingApiEndpoint(query) {
    const baseUrl = window.location.origin;
    const baseApiUrl = `${baseUrl}/api/internal/storefront/v1/listingPage`;
    return `${baseApiUrl}?${query}`;
}

export function getCtaApiEndpoint(query) {
    const baseUrl = window.location.origin;
    const baseApiUrl = `${baseUrl}/api/internal/storefront/v1/cta`;
    return `${baseApiUrl}?${query}`;
}

export function getCartApiEndpoint(locale) {
    const baseUrl = window.location.origin;
    const baseApiUrl = locale
        ? `${baseUrl}/api/checkout/v1/cart/preview?locale=${convertToJavaLocale(locale)}`
        : `${baseUrl}/api/checkout/v1/cart/preview`;
    return baseApiUrl;
}

// build the querystring part of an url from passed parameters
export function buildListingPageApiQuery(filterQueries = [], sort = null, page = null, locale = null) {
    const urlParams = [
        // search input, not managed by components, needs to be taken into account when building query.
        // we just take the page's url q value and always append it. Components cannot modify that part
        ...getDefaultListingQueryParams([SEARCH_QUERY_KEY, PRODUCTLINE_QUERY_KEY]),
        // filters are added as is to the query
        ...filterQueries.map(query => `${query.id}=${query.value}`)
    ];
    if (sort) {
        urlParams.push(`${SORT_QUERY_KEY}=${sort}`);
    }
    if (page) {
        urlParams.push(`${PAGE_QUERY_KEY}=${page}`);
    }
    if (locale) {
        urlParams.push(`${LOCALE_KEY}=${locale}`);
    }
    return urlParams.join('&');
}

function getValidUrl(targetUrl) {
    try {
        return new URL(targetUrl);
    } catch (err) {
        return false;
    }
}

function isSameDomain(targetHostName) {
    try {
        const currentDomain = window.location.hostname.replace('www.', '');
        const targetDomain = targetHostName.replace('www.', '');
        return currentDomain === targetDomain;
    } catch {
        return false;
    }
}

export function getStorefrontUrl(locale) {
    const storefrontPathName = window.location.pathname + window.location.search;
    const newLocale = [locale];
    const pathNames = storefrontPathName.split('/').slice(2);
    return `/${newLocale.concat(pathNames).join('/')}`;
}

export function navigateTo(targetUrl) {
    const validUrl = getValidUrl(targetUrl);
    const targetHostname = validUrl ? validUrl.hostname : null;
    if (validUrl && !isSameDomain(targetHostname)) {
        window.open(targetUrl);
    } else {
        window.location.href = targetUrl;
    }
}

export function buildCompareUrl(compareBaseUrl, productIds = []) {
    const compareParams = productIds.map(id => `${COMPARE_QUERY_KEY}=${id}`);
    return `${compareBaseUrl}?${compareParams.join('&')}`;
}

function getListingUrlParams(locale, queryKey) {
    const listingUrlParams = [];
    if (queryKey) {
        listingUrlParams.push(`${SEARCH_QUERY_KEY}=${queryKey}`);
    }
    if (locale) {
        listingUrlParams.push(`${LOCALE_KEY}=${locale}`);
    }
    return listingUrlParams.join('&');
}

export function getListingUrl(locale, queryKey) {
    const baseUrl = window.location.origin;
    if (queryKey || locale) {
        return `${baseUrl}/listing?${getListingUrlParams(locale, queryKey)}`;
    }
    return `${baseUrl}/listing`;
}

function getListingUrlProductLinesParams(locale, id) {
    const listingUrlParams = [];
    if (id) {
        listingUrlParams.push(`${PRODUCTLINE_QUERY_KEY}=${id}`);
    }
    if (locale) {
        listingUrlParams.push(`${LOCALE_KEY}=${locale}`);
    }
    return listingUrlParams.join('&');
}

export function getListingUrlForProductLines(locale, id) {
    const baseUrl = window.location.origin;
    if (id || locale) {
        return `${baseUrl}/listing?${getListingUrlProductLinesParams(locale, id)}`;
    }
    return `${baseUrl}/listing`;
}
