import useAppDispatch from "@insite/client-framework/Common/Hooks/useAppDispatch";
import useAppSelector from "@insite/client-framework/Common/Hooks/useAppSelector";
import Zone from "@insite/client-framework/Components/Zone";
import ApplicationState from "@insite/client-framework/Store/ApplicationState";
import prepareCart from "@insite/client-framework/Store/Components/ProductRecommendations/Handlers/PrepareCart";
import { getCurrentCartState } from "@insite/client-framework/Store/Data/Carts/CartsSelector";
import loadCurrentCart from "@insite/client-framework/Store/Data/Carts/Handlers/LoadCurrentCart";
import { getCurrentPromotionsDataView } from "@insite/client-framework/Store/Data/Promotions/PromotionsSelectors";
import sendCartPageView from "@insite/client-framework/Store/Pages/Cart/Handlers/SendCartPageView";
import clearMessages from "@insite/client-framework/Store/Pages/CheckoutReviewAndSubmit/Handlers/ClearMessages";
import setIsPreloadingData from "@insite/client-framework/Store/Pages/CheckoutShipping/Handlers/SetIsPreloadingData";
import PageModule from "@insite/client-framework/Types/PageModule";
import PageProps from "@insite/client-framework/Types/PageProps";
import Modals from "@insite/content-library/Components/Modals";
import LoadingOverlay, { LoadingOverlayProps } from "@insite/mobius/LoadingOverlay";
import Page from "@insite/mobius/Page";
import React, { useEffect, useState } from "react";
import { connect, ResolveThunks } from "react-redux";
import { css } from "styled-components";

const mapDispatchToProps = {
    loadCurrentCart,
    setIsPreloadingData,
    clearMessages,
    prepareCart,
};

const mapStateToProps = (state: ApplicationState) => {
    const currentPromotionsDataView = getCurrentPromotionsDataView(state);
    const cartState = getCurrentCartState(state);
    const cart = cartState.value;
    const fullCartLoaded =
        cart && (cart.lineCount === 0 || (cart.cartLines && cart.cartLines.length === cart.lineCount));
    return {
        cart,
        isCartIsLoading: cartState.isLoading,
        fullCartLoaded,
        shouldLoadCart: !cartState.isLoading && !fullCartLoaded,
        shouldLoadPromotions: !currentPromotionsDataView.value && !currentPromotionsDataView.isLoading,
        isPreloadingData: state.pages.checkoutShipping.isPreloadingData,
    };
};

type Props = PageProps & ResolveThunks<typeof mapDispatchToProps> & ReturnType<typeof mapStateToProps>;

export interface CartPageStyles {
    loadingOverlay?: LoadingOverlayProps;
}

export const cartPageStyles: CartPageStyles = {
    loadingOverlay: {
        css: css`
            width: 100%;
        `,
    },
};

const styles = cartPageStyles;

const CartPage = ({
    id,
    cart,
    isCartIsLoading,
    fullCartLoaded,
    shouldLoadCart,
    shouldLoadPromotions,
    isPreloadingData,
    setIsPreloadingData,
    loadCurrentCart,
    clearMessages,
    prepareCart,
}: Props) => {
    const [hasSentEvent, setHasSentEvent] = useState(false);
    const cartLines = useAppSelector(getCurrentCartState)?.value?.cartLines;
    const dispatch = useAppDispatch();

    useEffect(() => {
        if (!hasSentEvent && typeof cartLines !== "undefined") {
            dispatch(sendCartPageView({}));
            setHasSentEvent(true);
        }
    }, [hasSentEvent, cartLines]);

    useEffect(() => {
        if (shouldLoadCart) {
            loadCurrentCart({ getPromotions: true });
        }

        if (!shouldLoadPromotions && !shouldLoadCart && isPreloadingData) {
            setIsPreloadingData({ isPreloadingData: false });
        }
    });

    useEffect(() => {
        clearMessages();
    }, []);

    useEffect(() => {
        if (!isCartIsLoading && fullCartLoaded && cart) {
            prepareCart({ cart });
        }
    }, [isCartIsLoading, fullCartLoaded]);

    return (
        <Page>
            <LoadingOverlay {...styles.loadingOverlay} loading={isPreloadingData}>
                <Zone contentId={id} zoneName="Content"></Zone>
            </LoadingOverlay>
            <Modals />
        </Page>
    );
};

const pageModule: PageModule = {
    component: connect(mapStateToProps, mapDispatchToProps)(CartPage),
    definition: {
        hasEditableUrlSegment: true,
        hasEditableTitle: true,
        pageType: "System",
    },
};

export default pageModule;

/**
 * @deprecated Use string literal "CartPage" instead of this constant.
 */
export const CartPageContext = "CartPage";
