import { ProductInfo } from "@insite/client-framework/Common/ProductInfo";
import StyledWrapper from "@insite/client-framework/Common/StyledWrapper";
import { ProductContextModel } from "@insite/client-framework/Components/ProductContext";
import ApplicationState from "@insite/client-framework/Store/ApplicationState";
import { getSettingsCollection } from "@insite/client-framework/Store/Context/ContextSelectors";
import { getProductState } from "@insite/client-framework/Store/Data/Products/ProductsSelectors";
import replaceProduct from "@insite/client-framework/Store/Pages/MyListDetails/Handlers/ReplaceProduct";
import updateQuantity from "@insite/client-framework/Store/Pages/MyListDetails/Handlers/UpdateQuantity";
import updateUnitOfMeasure from "@insite/client-framework/Store/Pages/MyListDetails/Handlers/UpdateUnitOfMeasure";
import translate from "@insite/client-framework/Translate";
import { ProductModel, WishListLineModel, WishListModel } from "@insite/client-framework/Types/ApiModels";
import ProductBrand, { ProductBrandStyles } from "@insite/content-library/Components/ProductBrand";
import ProductDescription, { ProductDescriptionStyles } from "@insite/content-library/Components/ProductDescription";
import ProductImage, { ProductImageStyles } from "@insite/content-library/Components/ProductImage";
import ProductPartNumbers, { ProductPartNumbersStyles } from "@insite/content-library/Components/ProductPartNumbers";
import ProductPrice, { ProductPriceStyles } from "@insite/content-library/Components/ProductPrice";
import Button, { ButtonPresentationProps } from "@insite/mobius/Button";
import { BaseTheme } from "@insite/mobius/globals/baseTheme";
import GridContainer, { GridContainerProps } from "@insite/mobius/GridContainer";
import GridItem, { GridItemProps } from "@insite/mobius/GridItem";
import { HiddenProps } from "@insite/mobius/Hidden";
import Link, { LinkPresentationProps } from "@insite/mobius/Link";
import Modal, { ModalPresentationProps } from "@insite/mobius/Modal";
import ToasterContext from "@insite/mobius/Toast/ToasterContext";
import { TypographyPresentationProps } from "@insite/mobius/Typography";
import { breakpointMediaQueries } from "@insite/mobius/utilities";
import InjectableCss from "@insite/mobius/utilities/InjectableCss";
import cloneDeep from "lodash/cloneDeep";
import React, { useContext } from "react";
import { connect, ResolveThunks } from "react-redux";
import { css } from "styled-components";

interface OwnProps {
    isOpen: boolean;
    handleClose(): void;
    wishList: WishListModel;
    wishListLine: WishListLineModel;
    wishListLines: WishListLineModel[];
}

const mapStateToProps = (state: ApplicationState, ownProps: OwnProps) => {
    const productInfo = state.pages.myListDetails.replacementProductInfosByWishListLineId[ownProps.wishListLine.id];
    const settingsCollection = getSettingsCollection(state);

    return {
        productInfo,
        settingsCollection,
        loadWishListLinesParameter: state.pages.myListDetails.loadWishListLinesParameter,
    };
};

const mapDispatchToProps = {
    replaceProduct,
};

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

export interface ViewReplacementProductStyles {
    modal?: ModalPresentationProps;
    container?: GridContainerProps;
    imageGridItem?: GridItemProps;
    imageWrapper?: InjectableCss;
    productImageStyles?: ProductImageStyles;
    descriptionGridItem?: GridItemProps;
    productBrandStyles?: ProductBrandStyles;
    productDescriptionStyles?: ProductDescriptionStyles;
    partNumbersGridItem?: GridItemProps;
    productPartNumbersStyles?: ProductPartNumbersStyles;
    partNumbersHidden?: HiddenProps;
    priceStyles?: ProductPriceStyles;
    productInfoContainer?: GridContainerProps;
    cancelLink?: LinkPresentationProps;
    replaceButton?: ButtonPresentationProps;
    headlinePresentaionProps?: TypographyPresentationProps;
    productInformationGridItem?: GridItemProps;
    productPriceGridItem?: GridItemProps;
    buttonsGridItem?: GridItemProps;
    spacingGridItem?: GridItemProps;
}

export const viewReplacementProductStyles: ViewReplacementProductStyles = {
    modal: {
        cssOverrides: {
            modalTitle: css`
                align-items: center;
                padding: 15px 30px;
            `,
            modalContent: css`
                padding: 20px 30px;
            `,
            modalBody: css`
                overflow-y: visible;
            `,
        },
    },
    container: {
        gap: 10,
    },
    imageGridItem: {
        width: [2, 2, 2, 2, 2],
        printWidth: 1,
    },
    imageWrapper: {
        css: css`
            @media print {
                max-height: 83px;
                max-width: 83px;
            }
            width: 100%;
            min-width: 0;
            flex-direction: column;
        `,
    },
    descriptionGridItem: {
        width: [12, 12, 6, 6, 6],
        printWidth: 6,
        css: css`
            flex-direction: column;
        `,
    },
    partNumbersHidden: {
        below: "md",
        css: css`
            @media print {
                display: block;
            }
            width: 100%;
        `,
    },
    partNumbersGridItem: {
        width: 12,
        css: css`
            flex-direction: column;
        `,
    },
    priceStyles: {
        wrapper: {
            css: css`
                display: flex;
                flex-direction: column;
                ${({ theme }: { theme: BaseTheme }) =>
                    breakpointMediaQueries(
                        theme,
                        [
                            null,
                            null,
                            css`
                                align-self: flex-end;
                            `,
                        ],
                        "min",
                    )}
            `,
        },
    },
    productInfoContainer: {
        gap: 0,
    },
    cancelLink: {
        typographyProps: { size: 14 },
        css: css`
            margin-top: 10px;
        `,
    },
    replaceButton: {
        color: "primary",
        css: css`
            margin-left: 20px;
        `,
    },
    headlinePresentaionProps: {},
    productInformationGridItem: {
        width: [10, 10, 6, 6, 6],
        css: css`
            justify-content: right;
            flex-direction: column;
        `,
    },
    productPriceGridItem: {
        width: [10, 10, 4, 4, 4],
        css: css`
            align-self: flex-start;
        `,
    },
    buttonsGridItem: {
        width: 12,
        css: css`
            justify-content: right;
        `,
    },
    spacingGridItem: {
        width: [2, 2, 0, 0, 0],
    },
};

const styles = viewReplacementProductStyles;

const ViewReplacementProductModal = ({
    isOpen,
    handleClose,
    wishList,
    wishListLines,
    wishListLine,
    productInfo,
    settingsCollection,
    replaceProduct,
}: Props) => {
    const toasterContext = useContext(ToasterContext);
    const { productSettings } = settingsCollection;
    const product = mapWishListLineToProduct(wishListLine);

    const onReplaceClick = () => {
        handleClose();

        replaceProduct({
            wishListId: wishList.id,
            wishListLine,
            wishListLines,
        });

        toasterContext.addToast({ body: translate("Item Added"), messageType: "success" });
    };

    if (!product || !productInfo) {
        return null;
    }

    const replacementProductContext: ProductContextModel = {
        product,
        productInfo,

        onQtyOrderedChanged: qtyOrdered => {
            updateQuantity({ wishListLineId: wishListLine.id, qtyOrdered });
        },
        onUnitOfMeasureChanged: unitOfMeasure => {
            updateUnitOfMeasure({ wishListLineId: wishListLine.id, unitOfMeasure });
        },
    };

    return (
        <Modal
            {...styles.modal}
            handleClose={handleClose}
            headline={translate("Replacement Product")}
            isOpen={isOpen}
            size={600}
            isCloseable={true}
            headlineTypographyProps={styles.headlinePresentaionProps}
        >
            <GridContainer {...styles.container} data-test-selector="viewReplacementProduct">
                <GridItem {...styles.imageGridItem}>
                    <StyledWrapper {...styles.imageWrapper}>
                        <ProductImage product={replacementProductContext} extendedStyles={styles.productImageStyles} />
                    </StyledWrapper>
                </GridItem>
                <GridItem {...styles.productInformationGridItem}>
                    {replacementProductContext.product.brand && (
                        <ProductBrand
                            brand={replacementProductContext.product.brand}
                            extendedStyles={styles.productBrandStyles}
                        />
                    )}

                    <ProductDescription
                        product={replacementProductContext}
                        extendedStyles={styles.productDescriptionStyles}
                    />

                    <ProductPartNumbers
                        productNumber={replacementProductContext.product.productNumber}
                        customerProductNumber={replacementProductContext.product.customerProductNumber}
                        manufacturerItem={replacementProductContext.product.manufacturerItem}
                        extendedStyles={styles.productPartNumbersStyles}
                    />
                </GridItem>
                <GridItem {...styles.spacingGridItem}></GridItem>
                <GridItem {...styles.productPriceGridItem}>
                    <ProductPrice
                        product={replacementProductContext}
                        showSavings={true}
                        showLabel={false}
                        showSalePriceLabel={false}
                        showSavingsAmount={productSettings.showSavingsAmount}
                        showSavingsPercent={productSettings.showSavingsPercent}
                        extendedStyles={styles.priceStyles}
                    ></ProductPrice>
                </GridItem>
                <GridItem {...styles.buttonsGridItem}>
                    <Link
                        {...styles.cancelLink}
                        onClick={() => handleClose()}
                        data-test-selector="cancelReplaceProduct"
                    >
                        {translate("Cancel")}
                    </Link>

                    <Button
                        {...styles.replaceButton}
                        onClick={() => onReplaceClick()}
                        data-test-selector="replaceProduct"
                    >
                        {translate("Replace")}
                    </Button>
                </GridItem>
            </GridContainer>
        </Modal>
    );
};

const mapWishListLineToProduct = (wishListLine: WishListLineModel) => {
    if (!wishListLine.replacementProduct) {
        return null;
    }

    const product = cloneDeep(wishListLine.replacementProduct) as any as ProductModel;
    product.id = wishListLine.replacementProduct.id;
    product.productNumber = wishListLine.replacementProduct.erpNumber;
    product.productTitle = wishListLine.replacementProduct.shortDescription;
    product.customerProductNumber = wishListLine.replacementProduct.customerName;
    product.unitOfMeasures =
        wishListLine?.replacementProduct.productUnitOfMeasures?.map(u => ({
            id: u.productUnitOfMeasureId,
            ...u,
        })) || null;

    return product;
};

export default connect(mapStateToProps, mapDispatchToProps)(ViewReplacementProductModal);
