import useOverlayBadge from "@insite/client-framework/Common/Hooks/useOverlayBadge";
import mergeToNew from "@insite/client-framework/Common/mergeToNew";
import StyledWrapper from "@insite/client-framework/Common/StyledWrapper";
import wrapInContainerStyles from "@insite/client-framework/Common/wrapInContainerStyles";
import { HasProductContext, withProductContext } from "@insite/client-framework/Components/ProductContext";
import siteMessage from "@insite/client-framework/SiteMessage";
import ApplicationState from "@insite/client-framework/Store/ApplicationState";
import {
    getIsProductCompareFull,
    getProductCompareChecked,
} from "@insite/client-framework/Store/Components/CompareProductsDrawer/CompareProductsDrawerSelectors";
import addProductToCompare from "@insite/client-framework/Store/Components/CompareProductsDrawer/Handlers/AddProductToCompare";
import removeProductFromCompare from "@insite/client-framework/Store/Components/CompareProductsDrawer/Handlers/RemoveProductFromCompare";
import { getSettingsCollection } from "@insite/client-framework/Store/Context/ContextSelectors";
import translate from "@insite/client-framework/Translate";
import ProductImage, { ProductImageStyles } from "@insite/content-library/Components/ProductImage";
import Badge from "@insite/mobius/Badge";
import Checkbox, { CheckboxPresentationProps } from "@insite/mobius/Checkbox";
import { BaseTheme } from "@insite/mobius/globals/baseTheme";
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 React, { useContext, useState } from "react";
import { connect, ResolveThunks } from "react-redux";
import { css } from "styled-components";

interface OwnProps {
    showImage: boolean;
    showCompare: boolean;
    extendedStyles?: ProductListProductImageStyles;
    showTextBadge?: boolean;
    showImageBadge?: boolean;
}

const mapStateToProps = (state: ApplicationState, props: HasProductContext) => ({
    settingsCollection: getSettingsCollection(state),
    productCompareChecked: getProductCompareChecked(state, props.productContext),
    isProductCompareFull: getIsProductCompareFull(state),
});

const mapDispatchToProps = {
    addProductToCompare,
    removeProductFromCompare,
};

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

export interface ProductListProductImageStyles {
    wrapper?: InjectableCss;
    productImage?: ProductImageStyles;
    compareCheckbox?: CheckboxPresentationProps;
    badgeAreaWrapper?: InjectableCss;
    badgeTextWrapper?: InjectableCss;
    badgeImageWrapper?: InjectableCss;
    badgeText?: TypographyPresentationProps;
    badgeImageProps?: JSX.IntrinsicElements["img"];
}

export const productImageStyles: ProductListProductImageStyles = {
    wrapper: {
        css: css`
            display: flex;
            flex-direction: column;
            width: 100%;
        `,
    },
    compareCheckbox: {
        css: css`
            align-self: center;
            padding-top: 20px;
        `,
    },
    productImage: {
        image: {
            css: css`
                img {
                    min-width: 100%;
                }
                position: absolute;
                top: 0;
                left: 0;
                z-index: 0;
            `,
        },
    },
    badgeAreaWrapper: {
        css: css`
            position: relative;
        `,
    },
    badgeTextWrapper: {
        css: css`
            position: absolute;
            width: 50%;
            white-space: nowrap;
            overflow: hidden;
            ${({ theme }: { theme: BaseTheme }) =>
                breakpointMediaQueries(
                    theme,
                    [
                        null,
                        css`
                            width: 75%;
                        `,
                    ],
                    "max",
                )}
        `,
    },
    badgeImageWrapper: {
        css: css`
            position: absolute;
            width: 25%;
            height: 25%;
        `,
    },
    badgeText: {
        weight: "bold",
        css: css`
            width: 100%;
            margin: auto;
            ${wrapInContainerStyles}
            ${({ theme }: { theme: BaseTheme }) =>
                breakpointMediaQueries(
                    theme,
                    [
                        null,
                        css`
                            font-size: 10px;
                        `,
                    ],
                    "max",
                )}
        `,
    },
};

const ProductListProductImage = ({
    productContext,
    showImage,
    showTextBadge,
    showImageBadge,
    showCompare,
    isProductCompareFull,
    settingsCollection,
    productCompareChecked,
    extendedStyles,
    addProductToCompare,
    removeProductFromCompare,
}: Props) => {
    const toasterContext = useContext(ToasterContext);
    const [styles] = useState(() => mergeToNew(productImageStyles, extendedStyles));

    const {
        showOverlayBadge,
        overlayBadge,
        overlayBadgeWrapperStyles,
        badgeAreaWrapperRef,
        overlayBadgeWrapperClickHandler,
    } = useOverlayBadge({
        productContext,
        showTextBadge,
        showImageBadge,
        styles,
    });

    const handleChanged = (_: React.SyntheticEvent, value: boolean) => {
        if (value && isProductCompareFull) {
            toasterContext.addToast({
                body: siteMessage("ProductionCompare_MaximumItemsReached"),
                messageType: "warning",
            });
        } else if (value) {
            addProductToCompare({ productId: productContext.product.id });
        } else {
            removeProductFromCompare({ productId: productContext.product.id });
        }
    };

    return (
        <StyledWrapper
            {...styles.wrapper}
            data-test-selector="productListProductImage"
            data-test-key={productContext.product.id}
        >
            {showImage && !showOverlayBadge && (
                <ProductImage extendedStyles={styles.productImage} product={productContext} />
            )}
            {showImage && showOverlayBadge && overlayBadge && (
                <StyledWrapper
                    {...styles.badgeAreaWrapper}
                    ref={badgeAreaWrapperRef}
                    data-test-selector="productListBadge"
                >
                    <ProductImage extendedStyles={styles.productImage} product={productContext} />
                    <StyledWrapper {...overlayBadgeWrapperStyles} onClick={overlayBadgeWrapperClickHandler}>
                        <Badge
                            type={overlayBadge.badgeType}
                            value={
                                overlayBadge.badgeType === "Image"
                                    ? overlayBadge.largeImageBadgePath
                                    : overlayBadge.displayText
                            }
                            badgeTextColor={overlayBadge.textColorHexCode}
                            badgeBackgroundColor={overlayBadge.badgeColorHexCode}
                            badgeTextRounding={overlayBadge.badgeStyle === "Round" ? 20 : 0}
                            imageAltText={overlayBadge.imageAltText ? overlayBadge.imageAltText : overlayBadge.name}
                            textBadgeCss={styles.badgeText}
                            imageBadgeProps={styles.badgeImageProps}
                        />
                    </StyledWrapper>
                </StyledWrapper>
            )}
            {showCompare && settingsCollection.productSettings.enableProductComparisons && (
                <Checkbox
                    {...styles.compareCheckbox}
                    checked={productCompareChecked}
                    onChange={handleChanged}
                    data-test-selector="productList_CompareCheckbox"
                >
                    {translate("Compare")}
                </Checkbox>
            )}
        </StyledWrapper>
    );
};

export default withProductContext(connect(mapStateToProps, mapDispatchToProps)(ProductListProductImage));
