import mergeToNew from "@insite/client-framework/Common/mergeToNew";
import openPrintDialog from "@insite/client-framework/Common/Utilities/openPrintDialog";
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 { getCurrentAccountState } from "@insite/client-framework/Store/Data/Accounts/AccountsSelector";
import { getCurrentCartState } from "@insite/client-framework/Store/Data/Carts/CartsSelector";
import { getPageLinkByPageType } from "@insite/client-framework/Store/Links/LinksSelectors";
import approveOrder from "@insite/client-framework/Store/Pages/OrderApprovalDetails/Handlers/ApproveOrder";
import deleteOrder from "@insite/client-framework/Store/Pages/OrderApprovalDetails/Handlers/DeleteOrder";
import editOrder from "@insite/client-framework/Store/Pages/OrderApprovalDetails/Handlers/EditOrder";
import requestRevision from "@insite/client-framework/Store/Pages/OrderApprovalDetails/Handlers/RequestRevision";
import translate from "@insite/client-framework/Translate";
import { CartModel } from "@insite/client-framework/Types/ApiModels";
import TwoButtonModal, { TwoButtonModalStyles } from "@insite/content-library/Components/TwoButtonModal";
import Button, { ButtonPresentationProps } from "@insite/mobius/Button";
import Clickable, { ClickableProps } 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 Modal, { ModalPresentationProps } from "@insite/mobius/Modal";
import OverflowMenu, { OverflowMenuProps } from "@insite/mobius/OverflowMenu/OverflowMenu";
import TextArea, { TextAreaPresentationProps } from "@insite/mobius/TextArea";
import { HasToasterContext, withToaster } from "@insite/mobius/Toast/ToasterContext";
import Typography, { TypographyPresentationProps } from "@insite/mobius/Typography";
import { HasHistory, withHistory } from "@insite/mobius/utilities/HistoryContext";
import React, { useState } from "react";
import { connect, ResolveThunks } from "react-redux";
import { css } from "styled-components";

interface OwnProps {
    cart: CartModel;
    extendedStyles?: OrderApprovalDetailsActionButtonsStyles;
}

const mapStateToProps = (state: ApplicationState) => ({
    settingsCollection: getSettingsCollection(state),
    account: getCurrentAccountState(state)?.value,
    cartPageLink: getPageLinkByPageType(state, "CartPage"),
    orderApprovalListPageLink: getPageLinkByPageType(state, "OrderApprovalListPage"),
    homeLink: getPageLinkByPageType(state, "HomePage"),
});

const mapDispatchToProps = {
    approveOrder,
    deleteOrder,
    editOrder,
    requestRevision,
};

export interface OrderApprovalDetailsActionButtonsStyles {
    buttonsHiddenContainer?: HiddenProps;
    menuHiddenContainer?: HiddenProps;
    narrowOverflowMenu?: OverflowMenuProps;
    printButton?: ButtonPresentationProps;
    showActivityLogButton?: ButtonPresentationProps;
    continueShoppingButton?: ButtonPresentationProps;
    deleteButton?: ButtonPresentationProps;
    editButton?: ButtonPresentationProps;
    requestRevisionButton?: ButtonPresentationProps;
    approveButton?: ButtonPresentationProps;
    printClickable?: ClickableProps;
    showActivityLogClickable?: ClickableProps;
    continueShoppingClickable?: ClickableProps;
    deleteClickable?: ClickableProps;
    editClickable?: ClickableProps;
    requestRevisionClickable?: ClickableProps;
    approveClickable?: ClickableProps;
    twoButtonModalStyles?: TwoButtonModalStyles;
    requestRevisionModal?: ModalPresentationProps;
    requestRevisionContainer?: GridContainerProps;
    requestRevisionMessageGridItem?: GridItemProps;
    requestRevisionMessageText?: TypographyPresentationProps;
    requestRevisionMessageTextArea?: TextAreaPresentationProps;
    requestRevisionButtonsGridItem?: GridItemProps;
    requestRevisionSendRequestButton?: ButtonPresentationProps;
    requestRevisionCancelButton?: ButtonPresentationProps;
}

export const orderApprovalDetailsActionButtonsStyles: OrderApprovalDetailsActionButtonsStyles = {
    deleteButton: {
        css: css`
            margin-left: 10px;
        `,
        buttonType: "outline",
        variant: "secondary",
    },
    showActivityLogButton: {
        css: css`
            margin-left: 10px;
        `,
        buttonType: "outline",
        variant: "secondary",
    },
    editButton: {
        css: css`
            margin-left: 10px;
        `,
        buttonType: "outline",
        variant: "secondary",
    },
    requestRevisionButton: {
        css: css`
            margin-left: 10px;
        `,
        buttonType: "outline",
        variant: "secondary",
    },
    continueShoppingButton: {
        css: css`
            margin-left: 10px;
        `,
    },
    approveButton: {
        css: css`
            margin-left: 10px;
        `,
    },
    printButton: {
        variant: "secondary",
        buttonType: "solid",
    },
    buttonsHiddenContainer: {
        below: "lg",
    },
    menuHiddenContainer: {
        above: "md",
    },
    requestRevisionModal: {
        size: 600,
        cssOverrides: {
            modalContent: css`
                padding: 15px 30px 20px 30px;
            `,
        },
    },
    requestRevisionContainer: {
        gap: 10,
    },
    requestRevisionMessageGridItem: {
        width: 12,
        css: css`
            flex-direction: column;
        `,
    },
    requestRevisionMessageText: {
        css: css`
            margin-bottom: 20px;
        `,
    },
    requestRevisionButtonsGridItem: {
        width: 12,
        css: css`
            justify-content: flex-end;
        `,
    },
    requestRevisionCancelButton: {
        variant: "secondary",
        css: css`
            margin-right: 10px;
        `,
    },
};

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

const OrderApprovalDetailsActionButtons = ({
    cart,
    history,
    cartPageLink,
    orderApprovalListPageLink,
    homeLink,
    approveOrder,
    deleteOrder,
    editOrder,
    requestRevision,
    extendedStyles,
    account,
    toaster,
}: Props) => {
    const [styles] = useState(() => mergeToNew(orderApprovalDetailsActionButtonsStyles, extendedStyles));
    const [confirmationModalIsOpen, setConfirmationModalIsOpen] = useState(false);
    const [requestRevisionModalIsOpen, setRequestRevisionModalIsOpen] = useState(false);
    const [requestRevisionMessage, setRequestRevisionMessage] = useState("");
    const [isDisabledApproveButton, setIsDisabledApproveButton] = useState(false);

    if (!cart || !account || !orderApprovalListPageLink || !cartPageLink) {
        return null;
    }

    const isBuyerEditingOrder = cart.orderApprovalStatus === "EditingInProcess";
    const isRevisionRequested = cart.orderApprovalStatus === "RevisionRequested";
    const isApprovalInProcess = cart.orderApprovalStatus === "ApprovalInProcess";

    const approvalDisabled =
        cart.cartLines?.every(cartline => cartline.isRestricted) || isDisabledApproveButton || isBuyerEditingOrder;

    const printOrOpenPrintAllModal = () => {
        openPrintDialog();
    };

    const editClickHandler = async () => {
        editOrder({
            cart,
            onSuccess: () => {
                history.push(cartPageLink.url);
            },
        });
    };

    const continueShoppingClickHandler = () => {
        if (homeLink) {
            history.push(homeLink.url);
        }
    };

    const deleteClickHandler = () => {
        deleteOrder({
            onSuccess: () => {
                toaster.addToast({ body: translate("Order #{0} Deleted", cart.orderNumber), messageType: "success" });
                history.push(orderApprovalListPageLink.url);
            },
        });
    };

    const requestRevisionClickHandler = () => {
        setRequestRevisionModalIsOpen(true);
    };

    const requestRevisionModalCloseHandler = () => {
        setRequestRevisionModalIsOpen(false);
    };

    const approveClickHandler = () => {
        setIsDisabledApproveButton(true);

        approveOrder({
            onSuccess: () => {
                history.push(cartPageLink.url);
            },
            onComplete() {
                setTimeout(() => {
                    setIsDisabledApproveButton(false);
                }, 500);
            },
        });
    };

    const requestRevisionMessageChangeHandler = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
        setRequestRevisionMessage(event.target.value);
    };

    const sendRequestButtonClickHandler = () => {
        requestRevision({
            cart,
            requestRevisionMessage,
            onSuccess: () => {
                toaster.addToast({ body: translate("Request sent"), messageType: "success" });
            },
        });
    };

    const printLabel = translate("Print");
    const deleteLabel = translate("Delete");
    const editLabel = translate("Edit");
    const requestRevisionLabel = translate("Request Revision");
    const approveLabel = translate("Approve");
    const continueShoppingLabel = translate("Continue Shopping");

    return (
        <>
            <Hidden {...styles.menuHiddenContainer}>
                <OverflowMenu position="end" {...styles.narrowOverflowMenu}>
                    <Clickable {...styles.printClickable} onClick={printOrOpenPrintAllModal}>
                        {printLabel}
                    </Clickable>
                    <Clickable
                        {...styles.deleteClickable}
                        disabled={isBuyerEditingOrder || isApprovalInProcess}
                        onClick={() => setConfirmationModalIsOpen(true)}
                    >
                        {deleteLabel}
                    </Clickable>
                    {account.canApproveOrders ? (
                        <>
                            <Clickable
                                disabled={isBuyerEditingOrder || isRevisionRequested || isApprovalInProcess}
                                {...styles.requestRevisionClickable}
                                onClick={requestRevisionClickHandler}
                            >
                                {requestRevisionLabel}
                            </Clickable>
                            <Clickable
                                disabled={approvalDisabled}
                                {...styles.approveClickable}
                                onClick={approveClickHandler}
                            >
                                {approveLabel}
                            </Clickable>
                        </>
                    ) : (
                        <>
                            <Clickable
                                {...styles.editClickable}
                                disabled={isApprovalInProcess}
                                onClick={editClickHandler}
                            >
                                {editLabel}
                            </Clickable>
                            <Clickable {...styles.continueShoppingClickable} onClick={continueShoppingClickHandler}>
                                {continueShoppingLabel}
                            </Clickable>
                        </>
                    )}
                </OverflowMenu>
            </Hidden>
            <Hidden {...styles.buttonsHiddenContainer}>
                <Button
                    data-test-selector="orderApprovalDetails_print"
                    {...styles.printButton}
                    onClick={printOrOpenPrintAllModal}
                >
                    {printLabel}
                </Button>
                <Button
                    data-test-selector="orderApprovalDetails_deleteOrder"
                    {...styles.deleteButton}
                    disabled={isBuyerEditingOrder || isApprovalInProcess}
                    onClick={() => setConfirmationModalIsOpen(true)}
                >
                    {deleteLabel}
                </Button>
                {account.canApproveOrders ? (
                    <>
                        <Button
                            data-test-selector="orderApprovalDetails_requestRevision"
                            disabled={isBuyerEditingOrder || isRevisionRequested || isApprovalInProcess}
                            {...styles.requestRevisionButton}
                            onClick={requestRevisionClickHandler}
                        >
                            {requestRevisionLabel}
                        </Button>
                        <Button
                            data-test-selector="orderApprovalDetails_approveOrder"
                            {...styles.approveButton}
                            disabled={approvalDisabled}
                            onClick={approveClickHandler}
                        >
                            {approveLabel}
                        </Button>
                    </>
                ) : (
                    <>
                        <Button
                            data-test-selector="orderApprovalDetails_editOrder"
                            {...styles.editButton}
                            disabled={isApprovalInProcess}
                            onClick={editClickHandler}
                        >
                            {editLabel}
                        </Button>
                        <Button
                            data-test-selector="orderApprovalDetails_continueShopping"
                            {...styles.continueShoppingButton}
                            onClick={continueShoppingClickHandler}
                        >
                            {continueShoppingLabel}
                        </Button>
                    </>
                )}
            </Hidden>
            <TwoButtonModal
                modalIsOpen={confirmationModalIsOpen}
                headlineText={translate("Delete Order")}
                messageText={translate("Do you want to delete order #{0}?", cart.orderNumber)}
                cancelButtonText={translate("Cancel")}
                submitButtonText={translate("Delete")}
                submitTestSelector="confirmDeleteOrderButton"
                extendedStyles={styles.twoButtonModalStyles}
                onCancel={() => setConfirmationModalIsOpen(false)}
                onSubmit={deleteClickHandler}
            ></TwoButtonModal>
            <Modal
                {...styles.requestRevisionModal}
                headline={translate("Request Revision")}
                isOpen={requestRevisionModalIsOpen}
                handleClose={requestRevisionModalCloseHandler}
            >
                <GridContainer {...styles.requestRevisionContainer}>
                    <GridItem {...styles.requestRevisionMessageGridItem}>
                        <Typography {...styles.requestRevisionMessageText}>
                            {siteMessage("OrderApproval_RequestRevisionMessage")}
                        </Typography>
                        <TextArea
                            label={translate("Add a note (optional)")}
                            placeholder={translate("Write a message...")}
                            value={requestRevisionMessage}
                            onChange={requestRevisionMessageChangeHandler}
                            data-test-selector="requestRevisionMessage"
                            {...styles.requestRevisionMessageTextArea}
                        />
                    </GridItem>
                    <GridItem {...styles.requestRevisionButtonsGridItem}>
                        <Button
                            {...styles.requestRevisionCancelButton}
                            onClick={requestRevisionModalCloseHandler}
                            data-test-selector="requestRevisionModalCancel"
                        >
                            {translate("Cancel")}
                        </Button>
                        <Button
                            {...styles.requestRevisionSendRequestButton}
                            onClick={sendRequestButtonClickHandler}
                            data-test-selector="requestRevisionModalSend"
                        >
                            {translate("Send request")}
                        </Button>
                    </GridItem>
                </GridContainer>
            </Modal>
        </>
    );
};

export default connect(
    mapStateToProps,
    mapDispatchToProps,
)(withHistory(withToaster(OrderApprovalDetailsActionButtons)));
