import useOverlayBadge from "@insite/client-framework/Common/Hooks/useOverlayBadge";
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 ApplicationState from "@insite/client-framework/Store/ApplicationState";
import setSelectedImageIndex from "@insite/client-framework/Store/Pages/ProductDetails/Handlers/SetSelectedImageIndex";
import { getSelectedImage } from "@insite/client-framework/Store/Pages/ProductDetails/ProductDetailsSelectors";
import { ImageModel } from "@insite/client-framework/Types/ApiModels";
import WidgetModule from "@insite/client-framework/Types/WidgetModule";
import WidgetProps from "@insite/client-framework/Types/WidgetProps";
import ProductImageCarousel, {
    ProductImageCarouselStyles,
} from "@insite/content-library/Components/ProductImageCarousel";
import ProductPrimaryImage, { ProductPrimaryImageStyles } from "@insite/content-library/Components/ProductPrimaryImage";
import Badge from "@insite/mobius/Badge";
import { LazyImageProps } from "@insite/mobius/LazyImage";
import { LoadingSpinnerProps } from "@insite/mobius/LoadingSpinner";
import Modal, { ModalPresentationProps } from "@insite/mobius/Modal";
import { TypographyPresentationProps } from "@insite/mobius/Typography";
import InjectableCss from "@insite/mobius/utilities/InjectableCss";
import React, { useState } from "react";
import { connect, ResolveThunks } from "react-redux";
import { css } from "styled-components";

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

const mapStateToProps = (state: ApplicationState, ownProps: HasProductContext) => ({
    selectedImage: getSelectedImage(state, ownProps.productContext.product),
    selectedImageIndex: state.pages.productDetails.selectedImageIndex,
});

const mapDispatchToProps = {
    setSelectedImageIndex,
};

export interface ProductDetailsPrimaryImageStyles {
    /**
     * @deprecated Use primaryImage styles instead.
     */
    centeringWrapper?: InjectableCss;
    hiddenWrapper?: InjectableCss;
    spinner?: LoadingSpinnerProps;
    image?: LazyImageProps;

    primaryImage?: ProductPrimaryImageStyles;
    fullPrimaryImageModal?: ModalPresentationProps;
    fullPrimaryImage?: ProductPrimaryImageStyles;
    imageCarousel?: ProductImageCarouselStyles;
    badgeAreaWrapper?: InjectableCss;
    badgeTextWrapper?: InjectableCss;
    badgeImageWrapper?: InjectableCss;
    badgeText?: TypographyPresentationProps;
    badgeImageProps?: JSX.IntrinsicElements["img"];
}

export const primaryImageStyles: ProductDetailsPrimaryImageStyles = {
    fullPrimaryImageModal: {
        cssOverrides: {
            modalContainer: css`
                width: auto;
            `,
            modalBody: css`
                width: auto;
                max-width: initial;
                max-height: initial !important;
            `,
            modalTitle: css`
                border-bottom: none;
                padding: 10px 10px 0;
            `,
            modalContent: css`
                text-align: center;
            `,
        },
    },
    fullPrimaryImage: {
        image: {
            css: css`
                img {
                    width: auto;
                    max-height: 70vh;
                }
            `,
        },
        img: {
            css: css`
                width: auto;
                max-height: 70vh;
            `,
        },
    },
    badgeAreaWrapper: {
        css: css`
            position: relative;
        `,
    },
    badgeTextWrapper: {
        css: css`
            position: absolute;
            width: 50%;
            white-space: nowrap;
            overflow: hidden;
        `,
    },
    badgeImageWrapper: {
        css: css`
            position: absolute;
            width: 25%;
            height: 25%;
        `,
    },
    badgeText: {
        weight: "bold",
        css: css`
            width: 100%;
            margin: auto;
            ${wrapInContainerStyles}
        `,
    },
};

const styles = primaryImageStyles;

const ProductDetailsPrimaryImage = ({
    productContext,
    selectedImage,
    selectedImageIndex,
    setSelectedImageIndex,
}: Props) => {
    const [fullPrimaryImageModalIsOpen, setFullImageModalIsOpen] = useState(false);
    const imageClickHandler = () => {
        setFullImageModalIsOpen(true);
    };
    const fullPrimaryImageModalCloseHandler = () => {
        setFullImageModalIsOpen(false);
    };

    const selectImageHandler = (index: number) => {
        setSelectedImageIndex({ index });
    };

    const { product } = productContext;
    if (!product) {
        return null;
    }

    const image =
        selectedImage ??
        ({
            id: product.id,
            imageAltText: product.imageAltText,
            imageType: "Static",
            largeImagePath: product.largeImagePath,
            mediumImagePath: product.mediumImagePath,
            smallImagePath: product.smallImagePath,
        } as ImageModel);

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

    const path = image.mediumImagePath || image.largeImagePath;
    if (!path) {
        return null;
    }

    return (
        <>
            {!showOverlayBadge && (
                <ProductPrimaryImage
                    product={product}
                    image={image}
                    onClick={imageClickHandler}
                    extendedStyles={styles.primaryImage}
                />
            )}
            {showOverlayBadge && overlayBadge && (
                <StyledWrapper {...styles.badgeAreaWrapper} ref={badgeAreaWrapperRef}>
                    <ProductPrimaryImage
                        product={product}
                        image={image}
                        onClick={imageClickHandler}
                        extendedStyles={styles.primaryImage}
                    />
                    <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>
            )}
            <Modal
                {...styles.fullPrimaryImageModal}
                isOpen={fullPrimaryImageModalIsOpen}
                handleClose={fullPrimaryImageModalCloseHandler}
            >
                <ProductPrimaryImage
                    product={product}
                    image={image}
                    useLargeImage={true}
                    extendedStyles={styles.fullPrimaryImage}
                />
                {product.images && product.images.length > 1 && (
                    <ProductImageCarousel
                        selectedIndex={selectedImageIndex}
                        onSelectImage={selectImageHandler}
                        extendedStyles={styles.imageCarousel}
                    />
                )}
            </Modal>
        </>
    );
};

const widgetModule: WidgetModule = {
    component: withProductContext(connect(mapStateToProps, mapDispatchToProps)(ProductDetailsPrimaryImage)),
    definition: {
        displayName: "Primary Image",
        group: "Product Details",
        allowedContexts: ["ProductDetailsPage"],
    },
};

export default widgetModule;
