const appendLinkElement = (relValue: string, hrefValue: string) => {
    const head = document.querySelector("head");
    const link = document.createElement("link");
    link.setAttribute("rel", relValue);
    link.setAttribute("href", hrefValue);
    head?.appendChild(link);
};

const getLinkElement = (relValue: string, hrefValue: string) => {
    const linkElement = getlinkElementList().find(
        l => l.getAttribute("rel") === relValue && l.getAttribute("href") === hrefValue,
    );
    return linkElement;
};

const getlinkElementList = () => {
    return Array.from(document.getElementsByTagName("link"));
};

const removeLinkElement = (relValue: string, hrefValue: string) => {
    const head = document.querySelector("head");
    const link = getLinkElement(relValue, hrefValue);
    if (link) {
        head?.removeChild(link);
    }
};

const hasLinksWithRelPrevNext = (prev: string, next: string) => {
    const relPrevrelNext = { hasPrev: false, hasNext: false };
    const linkElementList = getlinkElementList();
    relPrevrelNext.hasPrev = linkElementList.some(
        l => l.getAttribute("rel") === "prev" && l.getAttribute("href") === prev,
    );
    relPrevrelNext.hasNext = linkElementList.some(
        l => l.getAttribute("rel") === "next" && l.getAttribute("href") === next,
    );
    return relPrevrelNext;
};

const getCurrentQueryString = (search: string) => {
    if (typeof window !== "undefined") {
        return window.location.search ?? "";
    }

    return search ?? "";
};

const getCanonical = () => {
    return window.location.origin + window.location.pathname;
};

const updateCanonical = (search: string) => {
    let link = document.querySelector('link[rel="canonical"]');
    if (!link) {
        link = document.createElement("link");
        link.setAttribute("rel", "canonical");
        document.head.appendChild(link);
    }

    const currentCanonical = new URL(link.getAttribute("href") || getCanonical());
    currentCanonical.search = search;
    link.setAttribute("href", currentCanonical.toString());
};

const getPrevCurrentNextQueryString = (
    prevPageUrl: string,
    nextpageUrl: string,
    currentPage: number,
    filterQuery: string,
) => {
    let currentQueryString = "";
    filterQuery = filterQuery ?? "";
    if (currentPage === 1) {
        if (filterQuery && filterQuery.indexOf("page=") === -1) {
            if (filterQuery.indexOf("query=") >= 0) {
                const idx = filterQuery.indexOf("&");
                if (idx >= 0) {
                    currentQueryString = `?${filterQuery.slice(0, idx)}&page=1${filterQuery.slice(idx)}`;
                } else {
                    currentQueryString = `?${filterQuery}&page=1`;
                }
            } else {
                currentQueryString = `?page=1&${filterQuery}`;
            }
        } else {
            currentQueryString = filterQuery ? `?${filterQuery}` : `?page=1`;
        }
    } else {
        const search = `?page=${currentPage}`;
        currentQueryString = getCurrentQueryString(search);
    }

    const prevQueryString = prevPageUrl
        ? currentQueryString.replace(/page=[0-9]+/, `page=${(currentPage - 1).toString()}`)
        : "";
    const nextQueryString = nextpageUrl
        ? currentQueryString.replace(/page=[0-9]+/, `page=${(currentPage + 1).toString()}`)
        : "";

    return { prevQueryString, currentQueryString, nextQueryString };
};

export default getLinkElement;
export {
    appendLinkElement,
    getCanonical,
    getCurrentQueryString,
    getlinkElementList,
    getPrevCurrentNextQueryString,
    hasLinksWithRelPrevNext,
    removeLinkElement,
    updateCanonical,
};
