import { makeHandlerChainAwaitable } from "@insite/client-framework/HandlerCreator";
import { API_URL_CURRENT_FRAGMENT } from "@insite/client-framework/Services/ApiService";
import {
    addCart,
    AddCartApiParameter,
    getCart,
    GetCartApiParameter,
} from "@insite/client-framework/Services/CartService";
import siteMessage from "@insite/client-framework/SiteMessage";
import ApplicationState from "@insite/client-framework/Store/ApplicationState";
import setVmiCountsImportModalIsOpen from "@insite/client-framework/Store/Components/VmiCountsImportModal/Handlers/SetVmiCountsImportModalIsOpen";
import { getSession, getSettingsCollection } from "@insite/client-framework/Store/Context/ContextSelectors";
import removeVmiBins from "@insite/client-framework/Store/Data/VmiBins/Handlers/RemoveVmiBins";
import { VmiBinsDataViewContext } from "@insite/client-framework/Store/Data/VmiBins/VmiBinsSelectors";
import { isVmiAdmin } from "@insite/client-framework/Store/Data/VmiLocations/VmiLocationsSelectors";
import addCartLineCollectionFromVmiBins from "@insite/client-framework/Store/Pages/OrderUpload/Handlers/AddCartLineCollectionFromVmiBins";
import exportVmiProducts from "@insite/client-framework/Store/Pages/VmiBins/Handlers/ExportVmiProducts";
import selectVmiBinsChangedQty from "@insite/client-framework/Store/Pages/VmiBins/Handlers/HandleVmiBinsChangedQty";
import setCartRequestInProcess from "@insite/client-framework/Store/Pages/VmiBins/Handlers/SetCartRequestInProcess";
import { Actions } from "@insite/client-framework/Store/Pages/VmiBins/VmiBinsReducer";
import translate from "@insite/client-framework/Translate";
import { VmiBinModel } from "@insite/client-framework/Types/ApiModels";
import WidgetModule from "@insite/client-framework/Types/WidgetModule";
import WidgetProps from "@insite/client-framework/Types/WidgetProps";
import ProductAddedToCartMessage from "@insite/content-library/Components/ProductAddedToCartMessage";
import TwoButtonModal, { TwoButtonModalStyles } from "@insite/content-library/Components/TwoButtonModal";
import VmiCountsImportModal from "@insite/content-library/Components/VmiCountsImportModal";
import { BinsPageContext } from "@insite/content-library/Pages/VmiBinsPage";
import GridContainer, { GridContainerProps } from "@insite/mobius/GridContainer";
import GridItem, { GridItemProps } from "@insite/mobius/GridItem";
import Link, { LinkPresentationProps } from "@insite/mobius/Link";
import ToasterContext from "@insite/mobius/Toast/ToasterContext";
import Typography, { TypographyPresentationProps } from "@insite/mobius/Typography";
import React, { useContext, useState } from "react";
import { connect, ResolveThunks } from "react-redux";
import { css } from "styled-components";

const mapStateToProps = (state: ApplicationState) => {
    const session = getSession(state);
    const settings = getSettingsCollection(state);
    return {
        getVmiBinsParameter: state.pages.vmiBins.getVmiBinsParameter,
        selectedIds: state.pages.vmiBins.selectedVmiBins,
        selectVmiBinsChangedQtyIds: state.pages.vmiBins.selectVmiBinsChangedQty,
        isRemoving: state.data.vmiBins.isRemoving,
        cartRequestInProcess: state.pages.vmiBins.cartRequestInProcess,
        isVmiAdmin: isVmiAdmin(settings.orderSettings, session),
    };
};

const mapDispatchToProps = {
    removeVmiBins,
    exportVmiProducts,
    addCartLineCollectionFromVmiBins: makeHandlerChainAwaitable(addCartLineCollectionFromVmiBins),
    setVmiCountsImportModalIsOpen,
    setCartRequestInProcess,
    selectVmiBinsChangedQty,
};

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

export interface VmiBinsActionsStyles {
    container?: GridContainerProps;
    gridItem?: GridItemProps;
    removeLink?: LinkPresentationProps;
    reorderLink?: LinkPresentationProps;
    exportLink?: LinkPresentationProps;
    binsCountText?: TypographyPresentationProps;
    twoButtonModalStyles?: TwoButtonModalStyles;
    importLink?: LinkPresentationProps;
}

export const vmiBinsActionsStyles: VmiBinsActionsStyles = {
    container: {
        gap: 8,
        css: css`
            padding: 20px 0;
        `,
    },
    gridItem: {
        width: 12,
        css: css`
            > * {
                padding-right: 10px;
            }
        `,
    },
    twoButtonModalStyles: {
        submitButton: {
            color: "primary",
        },
    },
    removeLink: {
        css: css`
            margin-left: 15px;
        `,
    },
    reorderLink: {
        css: css`
            margin-left: 15px;
        `,
    },
    exportLink: {
        css: css`
            margin-left: 15px;
        `,
    },
};
const styles = vmiBinsActionsStyles;

const VmiBinsActions = ({
    getVmiBinsParameter,
    selectedIds,
    selectVmiBinsChangedQtyIds,
    removeVmiBins,
    exportVmiProducts,
    isRemoving,
    cartRequestInProcess,
    addCartLineCollectionFromVmiBins,
    setVmiCountsImportModalIsOpen,
    setCartRequestInProcess,
    isVmiAdmin,
    selectVmiBinsChangedQty,
}: Props) => {
    const [removeModalIsOpen, setRemoveModalIsOpen] = useState(false);
    const [replenishSelectedConfirmationIsOpen, setReplenishSelectedConfirmationIsOpen] = useState(false);
    const [confirmationReplenishVmiBinIds, setConfirmationReplenishVmiBinIds] = useState<string[]>([]);
    const [confirmationReplenishVmiBins, setConfirmationReplenishVmiBins] = useState<VmiBinModel[]>([]);

    const vmiBinsDataView = useContext(VmiBinsDataViewContext);

    const toasterContext = useContext(ToasterContext);

    if (!vmiBinsDataView.value || !vmiBinsDataView.pagination) {
        return null;
    }

    const { totalItemCount } = vmiBinsDataView.pagination;

    if (totalItemCount === 0) {
        return null;
    }

    const handleRemoveButtonClick = () => {
        setRemoveModalIsOpen(true);
    };

    const handleReplenishSelectedButtonClick = () => {
        if (vmiBinsDataView.value) {
            const newVmiBins: VmiBinModel[] = [];
            const skippedVmiBins: VmiBinModel[] = [];
            const vmiBinsSelected = vmiBinsDataView.value.filter(v => selectedIds[v.id]);
            const ids: string[] = [];
            vmiBinsSelected.forEach(vmiBin => {
                if (vmiBin.lastCountQty >= vmiBin.maximumQty) {
                    skippedVmiBins.push(vmiBin);
                    return;
                }
                const product = {
                    ...vmiBin.product,
                    qtyOrdered: vmiBin.maximumQty > vmiBin.lastCountQty ? vmiBin.maximumQty - vmiBin.lastCountQty : 1,
                };

                const newVmiBin = {
                    ...vmiBin,
                    product,
                };
                newVmiBins.push(newVmiBin);
                if (selectVmiBinsChangedQtyIds && selectVmiBinsChangedQtyIds[vmiBin.id]) {
                    ids.push(vmiBin.id);
                }
            });
            if (newVmiBins.length <= 0 && skippedVmiBins.length > 0) {
                toasterContext.addToast({
                    body: siteMessage("VMI_Bins_AllSelectedBinsAtMaximumQuantity"),
                    messageType: "warning",
                });
                return;
            }

            if (newVmiBins.length > 0) {
                if (skippedVmiBins.length > 0) {
                    setReplenishSelectedConfirmationIsOpen(true);
                    setConfirmationReplenishVmiBinIds(ids);
                    setConfirmationReplenishVmiBins(newVmiBins);
                    return;
                }
                selectVmiBinsChangedQty({ ids, action: Actions[Actions.Remove] });
                updateCart(newVmiBins);
            }
        }
    };
    const handleCancelReplenishSelectedModalButtonClick = () => {
        setReplenishSelectedConfirmationIsOpen(false);
    };

    const handleContinueReplenishSelectedModalButtonClick = () => {
        if (confirmationReplenishVmiBinIds.length > 0) {
            selectVmiBinsChangedQty({ ids: confirmationReplenishVmiBinIds, action: Actions[Actions.Remove] });
            setConfirmationReplenishVmiBinIds([]);
        }
        if (confirmationReplenishVmiBins.length > 0) {
            updateCart(confirmationReplenishVmiBins);
            setConfirmationReplenishVmiBins([]);
        }
        setReplenishSelectedConfirmationIsOpen(false);
    };

    const updateCart = (vmiBins: VmiBinModel[]) => {
        setCartRequestInProcess({ cartRequestInProcess: true });
        getCart({ cartId: API_URL_CURRENT_FRAGMENT } as GetCartApiParameter).then(
            result => {
                if (result.cart.status === "AlternateCart") {
                    addCartLineCollectionFromVmiBins({ vmiBins }).then(
                        () => showNotification(vmiBins.length > 1),
                        () => setCartRequestInProcess({ cartRequestInProcess: false }),
                    );
                } else {
                    addCart({ vmiLocationId: getVmiBinsParameter.vmiLocationId } as AddCartApiParameter).then(
                        () => {
                            getCart({ cartId: API_URL_CURRENT_FRAGMENT } as GetCartApiParameter).then(
                                () => {
                                    addCartLineCollectionFromVmiBins({ vmiBins }).then(
                                        () => showNotification(vmiBins.length > 1),
                                        () => setCartRequestInProcess({ cartRequestInProcess: false }),
                                    );
                                },
                                () => setCartRequestInProcess({ cartRequestInProcess: false }),
                            );
                        },
                        () => setCartRequestInProcess({ cartRequestInProcess: false }),
                    );
                }
            },
            () => setCartRequestInProcess({ cartRequestInProcess: false }),
        );
    };

    const showNotification = (isMultipleProduct: boolean) => {
        toasterContext.addToast({
            body: <ProductAddedToCartMessage isQtyAdjusted={false} multipleProducts={isMultipleProduct} />,
            messageType: "success",
        });
    };

    const handleExportSelectedButtonClick = () => {
        exportVmiProducts({ ids: selectedIds });
    };

    const handleExportAllButtonClick = () => {
        exportVmiProducts({ ids: {} });
    };

    const handleCancelModalButtonClick = () => {
        setRemoveModalIsOpen(false);
    };

    const handleDeleteModalButtonClick = () => {
        if (!getVmiBinsParameter.vmiLocationId) {
            return;
        }

        setRemoveModalIsOpen(false);
        removeVmiBins({
            vmiLocationId: getVmiBinsParameter.vmiLocationId,
            ids: Object.keys(selectedIds),
        });
    };

    const handleImportCountsClick = () => {
        setVmiCountsImportModalIsOpen({ modalIsOpen: true });
    };

    return (
        <>
            <GridContainer {...styles.container}>
                <GridItem {...styles.gridItem}>
                    <Link
                        {...styles.importLink}
                        onClick={handleImportCountsClick}
                        data-test-selector="vmiBinsActions_importCounts"
                    >
                        {translate("Import Counts")}
                    </Link>
                    {isVmiAdmin && (
                        <Link
                            {...styles.removeLink}
                            disabled={isRemoving || Object.keys(selectedIds).length === 0}
                            onClick={handleRemoveButtonClick}
                        >
                            {translate("Remove")}
                        </Link>
                    )}
                    <Link
                        {...styles.reorderLink}
                        disabled={isRemoving || cartRequestInProcess || Object.keys(selectedIds).length === 0}
                        onClick={handleReplenishSelectedButtonClick}
                        data-test-selector="vmiBinsActions_replenishSelected"
                    >
                        {translate("Replenish Selected")}
                    </Link>
                    <Link
                        {...styles.exportLink}
                        disabled={isRemoving || Object.keys(selectedIds).length === 0}
                        onClick={handleExportSelectedButtonClick}
                    >
                        {translate("Export Selected")}
                    </Link>
                    <Link {...styles.exportLink} disabled={isRemoving} onClick={handleExportAllButtonClick}>
                        {translate("Export All")}
                    </Link>
                </GridItem>
            </GridContainer>
            <TwoButtonModal
                modalIsOpen={removeModalIsOpen}
                headlineText={translate("Delete Product")}
                messageText={translate("This will delete all information assigned to this product")}
                cancelButtonText={translate("Cancel")}
                submitButtonText={translate("Delete")}
                extendedStyles={styles.twoButtonModalStyles}
                onCancel={handleCancelModalButtonClick}
                onSubmit={handleDeleteModalButtonClick}
            ></TwoButtonModal>
            <TwoButtonModal
                modalIsOpen={replenishSelectedConfirmationIsOpen}
                headlineText={translate("Some items exceed max quantity")}
                messageText={siteMessage("Vmi_Bins_ReplenishSelectedMaxQuantityConfirmationMessage")}
                cancelButtonText={translate("Cancel")}
                submitButtonText={translate("Continue")}
                extendedStyles={styles.twoButtonModalStyles}
                onCancel={handleCancelReplenishSelectedModalButtonClick}
                onSubmit={handleContinueReplenishSelectedModalButtonClick}
            ></TwoButtonModal>
            <VmiCountsImportModal />
        </>
    );
};

const widgetModule: WidgetModule = {
    component: connect(mapStateToProps, mapDispatchToProps)(VmiBinsActions),
    definition: {
        group: "VMI Bins",
        allowedContexts: [BinsPageContext],
    },
};

export default widgetModule;
