import useAppSelector from "@insite/client-framework/Common/Hooks/useAppSelector";
import mergeToNew from "@insite/client-framework/Common/mergeToNew";
import getLocalizedDateTime from "@insite/client-framework/Common/Utilities/getLocalizedDateTime";
import { ShareOptions } from "@insite/client-framework/Services/WishListService";
import siteMessage from "@insite/client-framework/SiteMessage";
import ApplicationState from "@insite/client-framework/Store/ApplicationState";
import { getSettingsCollection } from "@insite/client-framework/Store/Context/ContextSelectors";
import addWishListToCart from "@insite/client-framework/Store/Pages/Cart/Handlers/AddWishListToCart";
import translate from "@insite/client-framework/Translate";
import { CartLineCollectionModel, WishListModel } from "@insite/client-framework/Types/ApiModels";
import MyListsDetailsPageTypeLink from "@insite/content-library/Components/MyListsDetailsPageTypeLink";
import WishListSharingStatus, {
    WishListSharingStatusStyles,
} from "@insite/content-library/Components/WishListSharingStatus";
import Button, { ButtonPresentationProps } from "@insite/mobius/Button";
import Clickable, { ClickablePresentationProps } from "@insite/mobius/Clickable";
import GridContainer, { GridContainerProps } from "@insite/mobius/GridContainer";
import GridItem, { GridItemProps } from "@insite/mobius/GridItem";
import Hidden, { HiddenProps } from "@insite/mobius/Hidden";
import Icon, { IconPresentationProps } from "@insite/mobius/Icon";
import Star from "@insite/mobius/Icons/Star";
import StarX from "@insite/mobius/Icons/StarX";
import Tag from "@insite/mobius/Icons/Tag";
import LazyImage, { LazyImageProps } from "@insite/mobius/LazyImage";
import Link, { LinkPresentationProps } from "@insite/mobius/Link";
import OverflowMenu, { OverflowMenuPresentationProps } from "@insite/mobius/OverflowMenu";
import ToasterContext from "@insite/mobius/Toast/ToasterContext";
import Tooltip, { TooltipPresentationProps } from "@insite/mobius/Tooltip";
import Typography, { TypographyProps } from "@insite/mobius/Typography";
import React, { useContext } from "react";
import { connect, HandleThunkActionCreator } from "react-redux";
import { css } from "styled-components";

const mapStateToProps = (state: ApplicationState) => ({
    language: state.context.session.language,
    allowEditingOfWishLists: getSettingsCollection(state).wishListSettings.allowEditingOfWishLists,
    isUpdatingCart: state.context.isUpdatingCart,
});

interface OwnProps {
    wishList: WishListModel;
    extendedStyles?: WishListCardStyles;
    addWishListToCart: HandleThunkActionCreator<typeof addWishListToCart>;
    deleteWishList?: () => void;
    leaveWishList?: () => void;
    toggleFavorite?: () => void;
    toggleHide?: () => void;
}

type Props = ReturnType<typeof mapStateToProps> & OwnProps;

export interface WishListCardStyles {
    gridContainer?: GridContainerProps;
    wishListInfoGridItem?: GridItemProps;
    wishListInfoGridContainer?: GridContainerProps;
    basicInfoGridItem?: GridItemProps;
    basicInfoGridContainer?: GridContainerProps;
    detailLinkGridItem?: GridItemProps;
    descriptionGridItem?: GridItemProps;
    descriptionText?: TypographyProps;
    lastUpdatedGridItem?: GridItemProps;
    lastUpdatedText?: TypographyProps;
    extendedInfoGridItem?: GridItemProps;
    extendedInfoGridContainer?: GridContainerProps;
    productImagesGridItem?: GridItemProps;
    productImageLink?: LinkPresentationProps;
    productImage?: LazyImageProps;
    sharingStatusGridItem?: GridItemProps;
    sharingStatus?: WishListSharingStatusStyles;
    actionGridItem?: GridItemProps;
    actionGridMediumHidden?: HiddenProps;
    actionOverflowIcon?: IconPresentationProps;
    actionOverflowMenu?: OverflowMenuPresentationProps;
    actionAddToCartClickable?: ClickablePresentationProps;
    actionHideClickable?: ClickablePresentationProps;
    actionDeleteClickable?: ClickablePresentationProps;
    actionLeaveClickable?: ClickablePresentationProps;
    actionAddToCartButton?: ButtonPresentationProps;
    actionHideLink?: LinkPresentationProps;
    actionDeleteButton?: ButtonPresentationProps;
    actionLeaveButton?: ButtonPresentationProps;
    actionFavoriteClickable?: ClickablePresentationProps;
    basicIconGridContainer?: GridContainerProps;
    detailIconGridItem?: GridItemProps;
    starIcon?: IconPresentationProps;
    starXIcon?: IconPresentationProps;
    tagTooltip?: TooltipPresentationProps;
}

export const wishListCardStyles: WishListCardStyles = {
    gridContainer: {
        gap: 5,
    },
    wishListInfoGridItem: {
        width: [10, 10, 8, 10, 10],
        align: "middle",
    },
    basicInfoGridItem: { width: [12, 12, 5, 4, 4] },
    basicInfoGridContainer: {
        gap: 10,
        css: css`
            margin-left: 10px;
        `,
    },
    detailLinkGridItem: { width: 12 },
    descriptionGridItem: { width: 12 },
    descriptionText: { ellipsis: true },
    lastUpdatedGridItem: { width: 12 },
    extendedInfoGridItem: {
        width: [12, 12, 7, 8, 8],
        align: "middle",
    },
    productImageLink: {
        css: css`
            margin-right: 5px;
        `,
    },
    productImagesGridItem: {
        width: [12, 12, 12, 8, 8],
        css: css`
            flex-wrap: wrap;
        `,
    },
    productImage: {
        css: css`
            max-width: 75px;
            img {
                height: 100%;
            }
        `,
        errorTypographyProps: {
            size: 11,
            css: css`
                max-height: 65px;
            `,
        },
    },
    sharingStatusGridItem: { width: [12, 12, 12, 4, 4] },
    actionGridItem: {
        width: [2, 2, 4, 2, 2],
        align: "top",
        css: css`
            justify-content: flex-end;
        `,
    },
    actionGridMediumHidden: {
        css: css`
            width: 100%;
        `,
    },
    actionAddToCartButton: {
        color: "secondary",
        css: css`
            white-space: nowrap;
            width: 100%;
            padding: 0 10px;
        `, // keep text from wrapping
    },
    actionHideLink: {
        css: css`
            display: block;
            margin: 10px auto 0 auto;
        `,
    },
    actionDeleteButton: {
        variant: "secondary",
        css: css`
            width: 100%;
            margin-top: 10px;
        `,
    },
    actionLeaveButton: {
        variant: "secondary",
        css: css`
            width: 100%;
            margin-top: 10px;
        `,
    },
    sharingStatus: {
        privateTooltip: {
            cssOverrides: {
                tooltipContainer: css`
                    transform: translateX(-33%);
                `,
                tooltipArrow: css`
                    left: 33%;
                `,
            },
        },
    },
    basicIconGridContainer: {
        gap: 10,
        css: css`
            width: 15px;
            flex-shrink: 0;
        `,
        offsetCss: css`
            flex-direction: column;
        `,
    },
    actionFavoriteClickable: {
        css: css`
            width: 15px;
        `,
    },
    starIcon: {
        src: Star,
        size: 15,
    },
    starXIcon: {
        src: StarX,
        size: 15,
    },
    tagTooltip: {
        iconProps: {
            src: Tag,
            size: 15,
            css: css`
                margin: 4px 0;
            `,
        },
    },
};

const WishListCard = ({
    language,
    allowEditingOfWishLists,
    isUpdatingCart,
    extendedStyles,
    wishList,
    addWishListToCart,
    deleteWishList,
    leaveWishList,
    toggleFavorite,
    toggleHide,
}: Props) => {
    const toasterContext = useContext(ToasterContext);
    const isLoadingAnyList = useAppSelector(state => Object.keys(state.data.wishLists.isLoading).length > 0);

    const clickAddToCartHandler = (e: any) => {
        e.preventDefault();
        addWishListToCart({
            apiParameter: { wishListId: wishList.id },
            onSuccess: onAddAllToCartSuccess,
            onComplete(resultProps) {
                if (resultProps.apiResult) {
                    // "this" is targeting the object being created, not the parent SFC
                    this.onSuccess?.(resultProps.apiResult);
                } else if (resultProps.errorMessage) {
                    toasterContext.addToast({
                        body: resultProps.errorMessage,
                        messageType: "danger",
                    });
                }
            },
        });
    };

    const onAddAllToCartSuccess = (result: CartLineCollectionModel) => {
        toasterContext.addToast({
            body: result.notAllAddedToCart
                ? siteMessage("Lists_Items_Not_All_Added_To_Cart")
                : translate("List Added to Cart"),
            messageType: "success",
        });
    };

    const updatedOnDisplay = getLocalizedDateTime({
        dateTime: new Date(wishList.updatedOn),
        language,
        options: {
            year: "numeric",
            month: "numeric",
            day: "numeric",
        },
    });
    let lastUpdatedDisplay = `${translate("Updated")} ${updatedOnDisplay}`;
    if (wishList.updatedByDisplayName && !wishList.isAutogenerated) {
        lastUpdatedDisplay += ` ${translate("by")} ${wishList.updatedByDisplayName}`;
    }

    const canAddToCart = wishList.canAddToCart && !!wishList.wishListLinesCount && wishList.wishListLinesCount > 0;
    const addToCartLabel = translate("Add List to Cart");
    const toggleHideButtonText = wishList.isHidden ? translate("Unhide List") : translate("Hide List");
    const toggleFavoriteLabel = wishList.isFavorite
        ? translate("Remove from favorites")
        : translate("Add to favorites");
    const deleteLabel = translate("Delete");
    const leaveLabel = translate("Leave List");
    const [styles] = React.useState(() => mergeToNew(wishListCardStyles, extendedStyles));

    return (
        <GridContainer {...styles.gridContainer} data-test-selector="wishListCard">
            <GridItem {...styles.wishListInfoGridItem} data-test-selector={`${wishList.name}`}>
                <GridContainer {...styles.wishListInfoGridContainer}>
                    <GridItem {...styles.basicInfoGridItem}>
                        <GridContainer {...styles.basicIconGridContainer}>
                            {!wishList.isAutogenerated && (
                                <GridItem {...styles.detailIconGridItem}>
                                    <Clickable
                                        {...styles.actionFavoriteClickable}
                                        onClick={toggleFavorite}
                                        aria-label={toggleFavoriteLabel}
                                        data-test-selector={`myListsFavorite_${wishList.id}`}
                                        disabled={isLoadingAnyList}
                                    >
                                        {wishList.isFavorite && (
                                            <Icon
                                                {...styles.starXIcon}
                                                data-test-selector={`myListsFavoriteStarXIcon_${wishList.id}`}
                                            />
                                        )}
                                        {!wishList.isFavorite && (
                                            <Icon
                                                {...styles.starIcon}
                                                data-test-selector={`myListsFavoriteStarIcon_${wishList.id}`}
                                            />
                                        )}
                                    </Clickable>
                                </GridItem>
                            )}
                            {wishList.wishListTags && wishList.wishListTags.length > 0 && (
                                <GridItem
                                    {...styles.detailIconGridItem}
                                    data-test-selector={`myListsTags_${wishList.id}`}
                                >
                                    <Tooltip
                                        {...styles.tagTooltip}
                                        text={`${translate("Tags Assigned")}: ${wishList.wishListTags
                                            .map(o => o.tag)
                                            .join(", ")}`}
                                    />
                                </GridItem>
                            )}
                        </GridContainer>
                        <GridContainer {...styles.basicInfoGridContainer}>
                            <GridItem {...styles.detailLinkGridItem}>
                                <MyListsDetailsPageTypeLink
                                    title={wishList.name}
                                    wishListId={wishList.id}
                                    testSelector="wishListCardName"
                                />
                            </GridItem>
                            {wishList.description && (
                                <GridItem {...styles.descriptionGridItem}>
                                    <Typography
                                        {...styles.descriptionText}
                                        data-test-selector="wishListCardDescription"
                                    >
                                        {wishList.description}
                                    </Typography>
                                </GridItem>
                            )}
                            <GridItem {...styles.lastUpdatedGridItem}>
                                <Typography {...styles.lastUpdatedText} data-test-selector="wishListCardLastUpdated">
                                    {lastUpdatedDisplay}
                                </Typography>
                            </GridItem>
                        </GridContainer>
                    </GridItem>
                    <GridItem {...styles.extendedInfoGridItem}>
                        <GridContainer {...styles.extendedInfoGridContainer}>
                            <GridItem {...styles.productImagesGridItem} data-test-selector="productImagesGridItem">
                                {wishList.wishListLineCollection &&
                                    wishList.wishListLineCollection.length > 0 &&
                                    wishList.wishListLineCollection.slice(0, 3).map(line => (
                                        <Link
                                            key={line.id.toString()}
                                            {...styles.productImageLink}
                                            href={line.productUri}
                                        >
                                            <LazyImage
                                                {...styles.productImage}
                                                src={line.smallImagePath}
                                                altText={line.altText}
                                                title={line.altText}
                                            />
                                        </Link>
                                    ))}
                            </GridItem>
                            <GridItem {...styles.sharingStatusGridItem}>
                                <WishListSharingStatus extendedStyles={styles.sharingStatus} wishList={wishList} />
                            </GridItem>
                        </GridContainer>
                    </GridItem>
                </GridContainer>
            </GridItem>
            <GridItem {...styles.actionGridItem}>
                <Hidden above="sm">
                    <OverflowMenu position="end" {...styles.actionOverflowMenu}>
                        <Clickable
                            {...styles.actionAddToCartClickable}
                            disabled={!canAddToCart || isUpdatingCart}
                            onClick={clickAddToCartHandler}
                        >
                            {addToCartLabel}
                        </Clickable>
                        {!wishList.isAutogenerated && (
                            <Clickable {...styles.actionHideClickable} disabled={isLoadingAnyList} onClick={toggleHide}>
                                {toggleHideButtonText}
                            </Clickable>
                        )}
                        {allowEditingOfWishLists &&
                            !!deleteWishList &&
                            !wishList.isSharedList &&
                            !wishList.isAutogenerated && (
                                <Clickable {...styles.actionDeleteClickable} onClick={deleteWishList}>
                                    {deleteLabel}
                                </Clickable>
                            )}
                        {allowEditingOfWishLists &&
                            !!leaveWishList &&
                            wishList.isSharedList &&
                            wishList.shareOption !== ShareOptions.AllCustomerUsers && (
                                <Clickable {...styles.actionLeaveClickable} onClick={leaveWishList}>
                                    {leaveLabel}
                                </Clickable>
                            )}
                    </OverflowMenu>
                </Hidden>
                <Hidden {...styles.actionGridMediumHidden} below="md">
                    <Button
                        {...styles.actionAddToCartButton}
                        disabled={!canAddToCart || isUpdatingCart}
                        data-test-selector={`wishListAddToCartButton_${wishList.id}`}
                        onClick={clickAddToCartHandler}
                    >
                        {addToCartLabel}
                    </Button>
                    {!wishList.isAutogenerated && (
                        <Link
                            {...styles.actionHideLink}
                            onClick={toggleHide}
                            data-test-selector={`myListsHide_${wishList.id}`}
                            disabled={isLoadingAnyList}
                        >
                            {toggleHideButtonText}
                        </Link>
                    )}
                    {allowEditingOfWishLists &&
                        !!deleteWishList &&
                        !wishList.isSharedList &&
                        !wishList.isAutogenerated && (
                            <Button
                                {...styles.actionDeleteButton}
                                onClick={deleteWishList}
                                data-test-selector={`wishListCardDeleteButton_${wishList.id}`}
                            >
                                {deleteLabel}
                            </Button>
                        )}
                    {allowEditingOfWishLists &&
                        !!leaveWishList &&
                        wishList.isSharedList &&
                        wishList.shareOption !== ShareOptions.AllCustomerUsers && (
                            <Button
                                {...styles.actionLeaveButton}
                                onClick={leaveWishList}
                                data-test-selector={`wishListCardLeaveButton_${wishList.id}`}
                            >
                                {leaveLabel}
                            </Button>
                        )}
                </Hidden>
            </GridItem>
        </GridContainer>
    );
};

export default connect(mapStateToProps)(WishListCard);
