import parseQueryString from "@insite/client-framework/Common/Utilities/parseQueryString";
import { createHandlerChainRunner, Handler } from "@insite/client-framework/HandlerCreator";
import { updateCart } from "@insite/client-framework/Services/CartService";
import { ExternalProviderLinkModel } from "@insite/client-framework/Services/IdentityService";
import { deleteSession } from "@insite/client-framework/Services/SessionService";
import { getCurrentUserIsGuest } from "@insite/client-framework/Store/Context/ContextSelectors";
import { getCurrentCartState } from "@insite/client-framework/Store/Data/Carts/CartsSelector";
import { getLocation } from "@insite/client-framework/Store/Data/Pages/PageSelectors";
import { getPageLinkByPageType } from "@insite/client-framework/Store/Links/LinksSelectors";
import { Draft } from "immer";
import cloneDeep from "lodash/cloneDeep";

type HandlerType = Handler<{ externalProvider: ExternalProviderLinkModel }>;

export const UnassignCartFromGuest: HandlerType = async props => {
    const currentUserIsGuest = getCurrentUserIsGuest(props.getState());
    if (!currentUserIsGuest) {
        return;
    }

    const { value: cart } = getCurrentCartState(props.getState());
    if (!cart) {
        throw new Error("The cart is not loaded. Try reloading the page.");
    }

    if (cart.lineCount > 0) {
        const cartClone = cloneDeep(cart) as Draft<typeof cart>;
        cartClone.unassignCart = true;
        await updateCart({ cart: cartClone });
    }
};

export const SignOutGuest: HandlerType = async props => {
    const currentUserIsGuest = getCurrentUserIsGuest(props.getState());
    if (!currentUserIsGuest) {
        return;
    }

    await deleteSession();
    props.dispatch({
        type: "Context/DeleteSession",
    });
};

export const RedirectToExternalProvider: HandlerType = ({ parameter: { externalProvider }, getState }) => {
    if (!externalProvider.url) {
        return;
    }

    const signInUrl = getPageLinkByPageType(getState(), "SignInPage")?.url;
    const location = getLocation(getState());

    let returnUrl = "/";
    if (signInUrl && location.pathname.toLowerCase() === signInUrl.toLowerCase()) {
        returnUrl = parseQueryString<{ returnUrl?: string }>(location.search).returnUrl || "/";
    } else {
        returnUrl = `${location.pathname}${location.search}`;
    }

    returnUrl = `${returnUrl + (returnUrl.indexOf("?") > -1 ? "&" : "?")}forcereturnurl`;
    returnUrl = encodeURIComponent(returnUrl);

    window.location.href = externalProvider.url.replace("returnurl%3a%2f", `returnurl%3a${returnUrl}`);
};

export const chain = [UnassignCartFromGuest, SignOutGuest, RedirectToExternalProvider];

const signInExternalProvider = createHandlerChainRunner(chain, "SignInExternalProvider");
export default signInExternalProvider;
