import StyledWrapper from "@insite/client-framework/Common/StyledWrapper";
import parseQueryString from "@insite/client-framework/Common/Utilities/parseQueryString";
import { API_URL_CURRENT_FRAGMENT } from "@insite/client-framework/Services/ApiService";
import { addCart, AddCartApiParameter } from "@insite/client-framework/Services/CartService";
import { GetVmiLocationsApiParameter } from "@insite/client-framework/Services/VmiLocationService";
import ApplicationState from "@insite/client-framework/Store/ApplicationState";
import { getSession, getSettingsCollection } from "@insite/client-framework/Store/Context/ContextSelectors";
import loadCurrentCart from "@insite/client-framework/Store/Data/Carts/Handlers/LoadCurrentCart";
import removeCart from "@insite/client-framework/Store/Data/Carts/Handlers/RemoveCart";
import { getById } from "@insite/client-framework/Store/Data/DataState";
import { getLocation } from "@insite/client-framework/Store/Data/Pages/PageSelectors";
import { getVmiBinsDataView } from "@insite/client-framework/Store/Data/VmiBins/VmiBinsSelectors";
import { isVmiAdmin } from "@insite/client-framework/Store/Data/VmiLocations/VmiLocationsSelectors";
import { getVmiLocationsDataView } from "@insite/client-framework/Store/Data/VmiLocations/VmiLocationsSelectors";
import { getPageLinkByPageType } from "@insite/client-framework/Store/Links/LinksSelectors";
import setIsReorderConfirmationModalOpen from "@insite/client-framework/Store/Pages/VmiBins/Handlers/SetIsReorderConfirmationModalOpen";
import setNextPageUrl from "@insite/client-framework/Store/Pages/VmiBins/Handlers/SetNextPageUrl";
import toggleFiltersOpen from "@insite/client-framework/Store/Pages/VmiBins/Handlers/ToggleFiltersOpen";
import updateSearchFields from "@insite/client-framework/Store/Pages/VmiBins/Handlers/UpdateSearchFields";
import translate from "@insite/client-framework/Translate";
import WidgetModule from "@insite/client-framework/Types/WidgetModule";
import WidgetProps from "@insite/client-framework/Types/WidgetProps";
import ReorderConfirmationModal from "@insite/content-library/Components/ReorderConfirmationModal";
import VmiAddProductModal from "@insite/content-library/Components/VmiAddProductModal";
import VmiBinsImportModal from "@insite/content-library/Components/VmiBinsImportModal";
import VmiCartRemovalConfirmModal from "@insite/content-library/Components/VmiCartRemovalConfirmModal";
import { BinsPageContext } from "@insite/content-library/Pages/VmiBinsPage";
import Button, { ButtonIcon, ButtonIconPresentationProps, ButtonPresentationProps } from "@insite/mobius/Button";
import Clickable from "@insite/mobius/Clickable";
import GridContainer, { GridContainerProps } from "@insite/mobius/GridContainer";
import GridItem, { GridItemProps } from "@insite/mobius/GridItem";
import Hidden from "@insite/mobius/Hidden";
import { IconProps } from "@insite/mobius/Icon";
import Filter from "@insite/mobius/Icons/Filter";
import LoadingSpinner, { LoadingSpinnerProps } from "@insite/mobius/LoadingSpinner";
import OverflowMenu, { OverflowMenuPresentationProps } from "@insite/mobius/OverflowMenu";
import Select, { SelectPresentationProps } from "@insite/mobius/Select";
import Typography, { TypographyPresentationProps } from "@insite/mobius/Typography";
import { HasHistory, withHistory } from "@insite/mobius/utilities/HistoryContext";
import InjectableCss from "@insite/mobius/utilities/InjectableCss";
import React, { Component } from "react";
import { connect, ResolveThunks } from "react-redux";
import { css } from "styled-components";

const mapStateToProps = (state: ApplicationState) => {
    const getVmiLocationsParameter = {
        filter: "",
        sort: "Name",
        expand: ["customerlabel"],
        page: 1,
        pageSize: 9999, // need to get all locations
    } as GetVmiLocationsApiParameter;

    const location = getLocation(state);
    const parsedQuery = parseQueryString<{ locationid?: string }>(location.search?.toLowerCase());
    const currentCart = getById(state.data.carts, API_URL_CURRENT_FRAGMENT).value;
    const session = getSession(state);
    const settings = getSettingsCollection(state);

    return {
        vmiLocationsDataView: getVmiLocationsDataView(state, getVmiLocationsParameter),
        vmiBinsPageUrl: getPageLinkByPageType(state, "VmiBinsPage")?.url,
        vmiLocationId: state.pages.vmiBins.getVmiBinsParameter.vmiLocationId,
        parsedQuery,
        cartVmiLocationId: currentCart?.vmiLocationId ?? "",
        cartLineCount: currentCart?.lineCount ?? 0,
        cartStatus: currentCart?.status ?? "",
        cartRequestInProcess: state.pages.vmiBins.cartRequestInProcess,
        isVmiAdmin: isVmiAdmin(settings.orderSettings, session),
        vmiBinsDataview: getVmiBinsDataView(state, state.pages.vmiBins.getVmiBinsParameter),
        isReorderConfirmationModalOpen: state.pages.vmiBins.isReorderConfirmationModalOpen,
        hasChangeLastQty:
            state.pages.vmiBins.selectVmiBinsChangedQty &&
            Object.keys(state.pages.vmiBins.selectVmiBinsChangedQty).length > 0,
    };
};

const mapDispatchToProps = {
    toggleFiltersOpen,
    updateSearchFields,
    loadCurrentCart,
    removeCart,
    setIsReorderConfirmationModalOpen,
    setNextPageUrl,
};

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

export interface VmiLocationsHeaderStyles {
    centeringWrapper?: InjectableCss;
    spinner?: LoadingSpinnerProps;
    gridContainer?: GridContainerProps;
    titleGridItem?: GridItemProps;
    buttonsGridItem?: GridItemProps;
    titleText?: TypographyPresentationProps;
    overflowMenu?: OverflowMenuPresentationProps;
    addProductButton?: ButtonPresentationProps;
    container?: GridContainerProps;
    locationSwitcherGridItem?: GridItemProps;
    locationSelect?: SelectPresentationProps;
    toggleFilterGridItem?: GridItemProps;
    toggleFilterGridItemUser?: GridItemProps;
    /** @deprecated Use toggleFilterButtonIcon instead. */
    toggleFilterIcon?: IconProps;
    toggleFilterButton?: ButtonPresentationProps;
    toggleFilterButtonIcon?: ButtonIconPresentationProps;
    binsCountText?: TypographyPresentationProps;
    totalGridItem?: GridItemProps;
}

export const headerStyles: VmiLocationsHeaderStyles = {
    centeringWrapper: {
        css: css`
            height: 100px;
            display: flex;
            align-items: center;
        `,
    },
    spinner: {
        css: css`
            margin: auto;
        `,
    },
    titleGridItem: {
        width: [10, 10, 8, 9, 9],
    },
    locationSwitcherGridItem: {
        css: css`
            justify-content: flex-end;
        `,
        width: [2, 2, 4, 3, 3],
    },
    titleText: {
        variant: "h2",
    },
    container: {
        gap: 8,
        css: css`
            padding-bottom: 10px;
        `,
    },
    buttonsGridItem: {
        width: [12, 12, 10, 10, 10],
        style: { marginTop: "8px", justifyContent: "flex-end" },
    },
    locationSelect: {
        cssOverrides: {
            formInputWrapper: css`
                width: 230px;
                align-self: end;
            `,
            inputSelect: css`
                text-transform: uppercase;
            `,
        },
    },
    toggleFilterGridItem: {
        width: [12, 12, 1, 1, 1],
        style: { marginTop: "8px", justifyContent: "flex-end", alignSelf: "center" },
    },
    toggleFilterGridItemUser: {
        width: [12, 12, 11, 11, 11],
        style: { marginTop: "8px", justifyContent: "flex-end", alignSelf: "center" },
    },
    toggleFilterButton: {
        color: "common.background",
        shape: "pill",
        buttonType: "solid",
        shadow: false,
        css: css`
            width: 40px;
            padding: 0;
        `,
    },
    toggleFilterButtonIcon: {
        src: Filter,
        size: 24,
    },
    totalGridItem: {
        style: { marginTop: "20px" },
    },
};

const styles = headerStyles;

interface State {
    isAddProductModalOpen: boolean;
    isConfirmModalOpen: boolean;
    selectedLocationId: string;
    cartLocationName: string;
}

class VmiBinsHeader extends Component<Props, State> {
    state = {
        isAddProductModalOpen: false,
        isConfirmModalOpen: false,
        selectedLocationId: "",
        cartLocationName: "",
    };

    onCancelRemoveCart = () => {
        this.setState({ isConfirmModalOpen: false });
    };

    onSubmitRemoveCart = (locationId: string) => {
        this.setState({ isConfirmModalOpen: false });
        this.removeAndCreateNewCart(locationId);
    };

    addProductClickHandler = () => {
        this.setState({ isAddProductModalOpen: true });
    };

    onSuccessAddProductModal = () => {};

    onCloseAddProductModal = () => {
        this.setState({ isAddProductModalOpen: false });
    };

    removeAndCreateNewCart = (locationId: string) => {
        this.props.removeCart({
            cartId: API_URL_CURRENT_FRAGMENT,
            isAlternateCart: true,
            onSuccess: () => {
                addCart({ vmiLocationId: locationId } as AddCartApiParameter).then(result => {
                    if (result?.successful) {
                        this.props.history.push(
                            `${this.props.vmiBinsPageUrl}${locationId ? `?locationId=${locationId}` : ""}`,
                        );
                        this.props.loadCurrentCart();
                    } else if (result?.statusCode === 403) {
                        window.location.reload();
                    }
                });
            },
        });
    };

    setLocation = (locationId: string) => {
        if (this.props.vmiBinsPageUrl) {
            if (!locationId) {
                this.props.history.push(`${this.props.vmiBinsPageUrl}`);
                this.props.updateSearchFields({ vmiLocationId: undefined });
                return;
            }
            const nextPageUrl = `${this.props.vmiBinsPageUrl}?locationId=${locationId}`;
            if (this.props.cartStatus === "AlternateCart") {
                if (this.props.cartVmiLocationId !== locationId) {
                    if (this.props.cartLineCount > 0) {
                        // Show confirmation to remove current cart
                        const vmiLocations = this.props.vmiLocationsDataView?.value;
                        const cartLocation = vmiLocations
                            ? vmiLocations.find(location => location.id?.toLowerCase() === this.props.cartVmiLocationId)
                            : undefined;
                        this.setState({
                            isConfirmModalOpen: true,
                            selectedLocationId: locationId,
                            cartLocationName: cartLocation?.name ?? "",
                        });
                    } else if (!this.props.isReorderConfirmationModalOpen && this.props.hasChangeLastQty) {
                        this.props.setIsReorderConfirmationModalOpen({
                            isReorderConfirmationModalOpen: true,
                        });
                        this.props.setNextPageUrl({
                            nextPageUrl,
                        });
                    } else {
                        // Remove current cart and add a new cart
                        this.removeAndCreateNewCart(locationId);
                    }
                } else {
                    this.props.history.push(nextPageUrl);
                    this.props.loadCurrentCart();
                }
            } else {
                addCart({ vmiLocationId: locationId } as AddCartApiParameter).then(() => {
                    this.props.history.push(nextPageUrl);
                    this.props.loadCurrentCart();
                });
            }
        }
    };

    render() {
        if (!this.props.vmiLocationsDataView.value || this.props.vmiLocationsDataView.isLoading) {
            return (
                <StyledWrapper {...styles.centeringWrapper}>
                    <LoadingSpinner {...styles.spinner} />
                </StyledWrapper>
            );
        }

        const vmiLocations = this.props.vmiLocationsDataView;
        let currentLocation = null;
        if (vmiLocations?.value && vmiLocations.value.length > 0) {
            const locationId = this.props.parsedQuery?.locationid?.toLowerCase() || this.props.vmiLocationId;
            currentLocation = locationId
                ? vmiLocations.value.find(location => location.id?.toLowerCase() === locationId)
                : null;
        }

        const vmiBinsDataView = this.props.vmiBinsDataview;
        let totalItemCount = 0;
        if (vmiBinsDataView.value && vmiBinsDataView.pagination) {
            totalItemCount = vmiBinsDataView.pagination.totalItemCount;
        }

        return (
            <>
                <GridContainer {...styles.gridContainer}>
                    <GridItem {...styles.titleGridItem}>
                        <Typography as="h2" {...styles.titleText}>
                            {translate("Products")}
                        </Typography>
                    </GridItem>
                    <GridItem {...styles.locationSwitcherGridItem}>
                        {vmiLocations && vmiLocations.value && (
                            <Select
                                {...styles.locationSelect}
                                disabled={this.props.cartRequestInProcess}
                                data-test-selector="locationSelector"
                                onChange={event => this.setLocation(event.currentTarget.value)}
                                value={currentLocation?.id ?? ""}
                                hasLabel
                            >
                                <option value="">{translate("Select Location")}</option>
                                {vmiLocations.value.map(c => (
                                    <option value={c.id} key={c.id}>
                                        {c.name}
                                    </option>
                                ))}
                            </Select>
                        )}
                    </GridItem>
                </GridContainer>
                <GridContainer {...styles.container}>
                    <GridItem {...styles.totalGridItem}>
                        {totalItemCount > 0 && (
                            <Typography {...styles.binsCountText}>
                                {totalItemCount} {translate("Products")}
                            </Typography>
                        )}
                    </GridItem>
                    {this.props.isVmiAdmin && (
                        <GridItem {...styles.buttonsGridItem}>
                            <Hidden above="sm">
                                <OverflowMenu position="end" {...styles.overflowMenu}>
                                    <Clickable onClick={this.addProductClickHandler}>
                                        {translate("Add Product")}
                                    </Clickable>
                                </OverflowMenu>
                            </Hidden>
                            <Hidden below="md">
                                <Button {...styles.addProductButton} onClick={this.addProductClickHandler}>
                                    {translate("Add Product")}
                                </Button>
                            </Hidden>
                        </GridItem>
                    )}
                    <GridItem
                        {...(this.props.isVmiAdmin ? styles.toggleFilterGridItem : styles.toggleFilterGridItemUser)}
                    >
                        <Button {...styles.toggleFilterButton} onClick={this.props.toggleFiltersOpen}>
                            <ButtonIcon {...styles.toggleFilterButtonIcon} />
                        </Button>
                    </GridItem>
                </GridContainer>
                <VmiAddProductModal
                    isOpen={this.state.isAddProductModalOpen}
                    onSuccess={this.onSuccessAddProductModal}
                    onClose={this.onCloseAddProductModal}
                />
                <VmiBinsImportModal />
                <VmiCartRemovalConfirmModal
                    modalIsOpen={this.state.isConfirmModalOpen}
                    vmiLocationId={this.state.selectedLocationId}
                    cartLocationName={this.state.cartLocationName}
                    onCancel={this.onCancelRemoveCart}
                    onSubmit={this.onSubmitRemoveCart}
                />
                <ReorderConfirmationModal />
            </>
        );
    }
}

const widgetModule: WidgetModule = {
    component: connect(mapStateToProps, mapDispatchToProps)(withHistory(VmiBinsHeader)),
    definition: {
        group: "VMI Bins",
        allowedContexts: [BinsPageContext],
    },
};

export default widgetModule;
