import getLocalizedDateTime from "@insite/client-framework/Common/Utilities/getLocalizedDateTime";
import ApplicationState from "@insite/client-framework/Store/ApplicationState";
import { getSettingsCollection } from "@insite/client-framework/Store/Context/ContextSelectors";
import { getWishListLinesDataView } from "@insite/client-framework/Store/Data/WishListLines/WishListLinesSelectors";
import resetWishLists from "@insite/client-framework/Store/Data/WishLists/Handlers/ResetWishLists";
import {
    getWishListState,
    getWishListTotal,
    getWishListTotalWithVat,
} from "@insite/client-framework/Store/Data/WishLists/WishListsSelectors";
import removeWishListTags from "@insite/client-framework/Store/Pages/MyListDetails/Handlers/RemoveWishListTags";
import translate from "@insite/client-framework/Translate";
import { WishListTagModel } from "@insite/client-framework/Types/ApiModels";
import WidgetModule from "@insite/client-framework/Types/WidgetModule";
import WidgetProps from "@insite/client-framework/Types/WidgetProps";
import LocalizedCurrency from "@insite/content-library/Components/LocalizedCurrency";
import SmallHeadingAndText, { SmallHeadingAndTextStyles } from "@insite/content-library/Components/SmallHeadingAndText";
import WishListSharingStatus, {
    WishListSharingStatusStyles,
} from "@insite/content-library/Components/WishListSharingStatus";
import { BaseTheme } from "@insite/mobius/globals/baseTheme";
import GridContainer, { GridContainerProps } from "@insite/mobius/GridContainer";
import GridItem, { GridItemProps } from "@insite/mobius/GridItem";
import X from "@insite/mobius/Icons/X";
import Typography, { TypographyPresentationProps, TypographyProps } from "@insite/mobius/Typography";
import breakpointMediaQueries from "@insite/mobius/utilities/breakpointMediaQueries";
import getColor from "@insite/mobius/utilities/getColor";
import React from "react";
import { connect } from "react-redux";
import { useDispatch } from "react-redux";
import { css } from "styled-components";

const mapStateToProps = (state: ApplicationState) => {
    const wishListLinesDataView = getWishListLinesDataView(state, state.pages.myListDetails.loadWishListLinesParameter);

    return {
        wishList: getWishListState(state, state.pages.myListDetails.wishListId).value,
        wishListTotal: getWishListTotal(wishListLinesDataView, state.pages.myListDetails.productInfosByWishListLineId),
        language: state.context.session.language,
        enableVat: getSettingsCollection(state).productSettings.enableVat,
        vatPriceDisplay: getSettingsCollection(state).productSettings.vatPriceDisplay,
        wishListTotalWithVat: getWishListTotalWithVat(
            wishListLinesDataView,
            state.pages.myListDetails.productInfosByWishListLineId,
        ),
        showPricing: state.context.showPricing,
        removingWishListTags: state.pages.myListDetails.removingWishListTags,
    };
};

type Props = WidgetProps & ReturnType<typeof mapStateToProps>;

export interface MyListsDetailsHeaderStyles {
    container?: GridContainerProps;
    infoGridItem?: GridItemProps;
    lastUpdateText?: TypographyProps;
    wishListHiddenText?: TypographyProps;
    sharingStatus?: WishListSharingStatusStyles;
    shareText?: TypographyProps;
    lineCountText?: TypographyProps;
    totalText?: TypographyProps;
    totalVatLabelText?: TypographyPresentationProps;
    totalWithoutVatText?: TypographyPresentationProps;
    totalWithoutVatLabelText?: TypographyPresentationProps;
    descriptionGridItem?: GridItemProps;
    descriptionStyles?: SmallHeadingAndTextStyles;
    tagsGridItem?: GridItemProps;
    tagText?: TypographyProps;
    tagCloseText?: TypographyProps;
}

export const headerStyles: MyListsDetailsHeaderStyles = {
    container: { gap: 15 },
    infoGridItem: {
        width: 12,
        css: css`
            align-items: flex-end;

            @media print {
                justify-content: flex-start;
                flex-direction: row !important;
            }
            ${({ theme }: { theme: BaseTheme }) =>
                breakpointMediaQueries(
                    theme,
                    [
                        null,
                        css`
                            flex-direction: column;
                        `,
                        null,
                        null,
                        css`
                            justify-content: flex-start;
                        `,
                    ],
                    "max",
                )}
        `,
    },
    sharingStatus: {
        statusText: {
            css: css`
                padding-left: 30px;
            `,
        },
        privateTooltip: {
            cssOverrides: {
                tooltipContainer: css`
                    margin-left: -200px;
                    &::after {
                        margin-left: 85px;
                    }
                `,
            },
        },
    },
    wishListHiddenText: {
        css: css`
            padding-left: 30px;
        `,
    },
    totalText: {
        weight: "bold",
        css: css`
            padding-left: 30px;
        `,
    },
    totalVatLabelText: {
        size: 12,
        css: css`
            margin-left: 5px;
        `,
    },
    totalWithoutVatText: {
        weight: "bold",
        css: css`
            margin-left: 5px;
        `,
    },
    totalWithoutVatLabelText: {
        size: 12,
        css: css`
            margin-left: 5px;
        `,
    },
    descriptionGridItem: { width: 12 },
    tagsGridItem: {
        width: 12,
        css: css`
            flex-wrap: wrap;
        `,
    },
    tagText: {
        css: css`
            display: flex;
            background: ${getColor("primary.main")};
            color: ${getColor("primary.contrast")};
            &:hover {
                background: #1b3f76;
            }
            border-radius: 4px;
            white-space: nowrap;
            margin-right: 6px;
            margin-bottom: 6px;
            padding: 2px 6px;
            font-size: 15px;
            align-items: center;
            padding-left: 14px;
        `,
    },
    tagCloseText: {
        css: css`
            line-height: 12px;
            margin-left: 6px;
            cursor: pointer;
        `,
    },
};

const styles = headerStyles;

const MyListsDetailsHeader = ({
    wishList,
    wishListTotal,
    language,
    enableVat,
    vatPriceDisplay,
    wishListTotalWithVat,
    showPricing,
    removingWishListTags,
}: Props) => {
    if (!wishList) {
        return null;
    }

    const dispatch = useDispatch();
    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 removeTag = (wishListTag: WishListTagModel) => {
        if (!removingWishListTags) {
            dispatch(
                removeWishListTags({
                    wishListId: wishList.id,
                    wishListTagIds: [wishListTag.id],
                    onComplete: () => dispatch(resetWishLists()),
                }),
            );
        }
    };

    return (
        <GridContainer {...styles.container}>
            <GridItem {...styles.infoGridItem}>
                <Typography {...styles.lastUpdateText} data-test-selector="lastUpdate">
                    {lastUpdatedDisplay}
                </Typography>
                {wishList.isHidden && (
                    <Typography {...styles.wishListHiddenText}>{translate("List is hidden")}</Typography>
                )}
                <WishListSharingStatus
                    extendedStyles={styles.sharingStatus}
                    showNoPermissionsTooltip={true}
                    wishList={wishList}
                />
                {wishListTotal !== undefined && showPricing && (
                    <>
                        <Typography {...styles.totalText} data-test-selector="listTotal">
                            {translate("List Total")}:{" "}
                            <LocalizedCurrency
                                amount={
                                    enableVat && vatPriceDisplay !== "DisplayWithoutVat" && wishListTotalWithVat
                                        ? wishListTotalWithVat
                                        : wishListTotal
                                }
                            />
                        </Typography>
                        {enableVat && (
                            <>
                                <Typography {...styles.totalVatLabelText}>
                                    {`(${
                                        vatPriceDisplay === "DisplayWithoutVat"
                                            ? translate("Ex. VAT")
                                            : translate("Inc. VAT")
                                    })`}
                                </Typography>
                                {vatPriceDisplay === "DisplayWithAndWithoutVat" && (
                                    <>
                                        <Typography {...styles.totalWithoutVatText}>
                                            <LocalizedCurrency amount={wishListTotal} />
                                        </Typography>
                                        <Typography {...styles.totalWithoutVatLabelText}>
                                            ({translate("Ex. VAT")})
                                        </Typography>
                                    </>
                                )}
                            </>
                        )}
                    </>
                )}
            </GridItem>
            {wishList.description && (
                <GridItem {...styles.descriptionGridItem}>
                    <SmallHeadingAndText
                        heading={translate("Description")}
                        text={wishList.description}
                        extendedStyles={styles.descriptionStyles}
                        data-test-selector="listDescription"
                    />
                </GridItem>
            )}
            {wishList.wishListTags && (
                <GridItem {...styles.tagsGridItem}>
                    {wishList.wishListTags.map(wishListTag => (
                        <Typography
                            {...styles.tagText}
                            key={wishListTag.tag}
                            data-test-selector={`tagItem_${wishListTag.tag}`}
                        >
                            {wishListTag.tag}
                            <Typography
                                {...styles.tagCloseText}
                                onClick={() => removeTag(wishListTag)}
                                data-test-selector={`removeTagItem_${wishListTag.tag}`}
                            >
                                <X />
                            </Typography>
                        </Typography>
                    ))}
                </GridItem>
            )}
        </GridContainer>
    );
};

const widgetModule: WidgetModule = {
    component: connect(mapStateToProps)(MyListsDetailsHeader),
    definition: {
        group: "My Lists Details",
        displayName: "Header",
        allowedContexts: ["MyListsDetailsPage"],
    },
};

export default widgetModule;
