import StyledWrapper from "@insite/client-framework/Common/StyledWrapper";
import { redoPageState } from "@insite/client-framework/Services/ContentService";
import Clickable from "@insite/mobius/Clickable";
import LoadingSpinner from "@insite/mobius/LoadingSpinner";
import Modal from "@insite/mobius/Modal";
import OverflowMenu, { OverflowMenuProps } from "@insite/mobius/OverflowMenu";
import getColor from "@insite/mobius/utilities/getColor";
import { StyledProp } from "@insite/mobius/utilities/InjectableCss";
import ArrowRight from "@insite/shell/Components/Icons/ArrowRight";
import AxiomIcon from "@insite/shell/Components/Icons/AxiomIcon";
import { HasRouter, withRouter } from "@insite/shell/Components/RouterContext";
import About from "@insite/shell/Components/Shell/About";
import { generateBlueprintTranslations } from "@insite/shell/Services/SpireService";
import shellTheme from "@insite/shell/ShellTheme";
import {
    showImportExportModal,
    showRestoreContentModal,
} from "@insite/shell/Store/ImportExportModal/ImportExportModalActionCreators";
import {
    logOut,
    toggleMobileCmsMode,
    toggleSearchDataModeActive,
} from "@insite/shell/Store/ShellContext/ShellContextActionCreators";
import ShellState from "@insite/shell/Store/ShellState";
import { TS } from "@insite/shell/TS";
import * as React from "react";
import { connect, ResolveThunks } from "react-redux";
import styled, { css } from "styled-components";

const mapStateToProps = ({
    shellContext: {
        mobileCmsModeActive,
        enableMobileCms,
        homePageId,
        mobileHomePageId,
        searchDataModeActive,
        permissions,
        settings,
    },
}: ShellState) => ({
    mobileCmsModeActive,
    enableMobileCms,
    homePageId,
    mobileHomePageId,
    searchDataModeActive,
    permissions,
    hasSearchDataModeCompatibleProvider:
        settings?.settingsCollection?.searchSettings.searchProvider !== "Commerce Search v3",
});

const mapDispatchToProps = {
    logOut,
    showImportExportModal,
    showRestoreContentModal,
    toggleMobileCmsMode,
    toggleSearchDataModeActive,
};

/** Fixes blackout caused by `OverflowMenu` using `common.border` for the background color, which in the Shell, is the same as the text. */
const menuItemStyles = css`
    &:hover {
        color: ${getColor("common.accentContrast")};
        background: ${getColor("common.accent")};
    }
` as any; // The type on the overflow menu doesn't like this but it works.

const wrapperStyles: StyledProp<OverflowMenuProps> = css`
    width: 24px;
`;

const wrapperContentManagementStyles: StyledProp<OverflowMenuProps> = css`
    width: 100%;
`;

const ArrowContainerStyle = styled.div`
    display: flex;
    cursor: pointer;
    width: 100%;
    font-size: 16px;

    span {
        text-align: left;
        padding: 0;

        &:focus {
            background: none;
            outline: none;
            color: inherit;
        }
    }
`;

const ContentManagementHeaderStyle = styled.div`
    padding-left: 15px;
    font-size: 14px;
    padding-top: 4px;
    color: #a4a4a4;
`;

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

const HeaderGear = ({
    mobileCmsModeActive,
    enableMobileCms,
    homePageId,
    mobileHomePageId,
    router,
    toggleMobileCmsMode,
    logOut,
    showImportExportModal,
    showRestoreContentModal,
    searchDataModeActive,
    toggleSearchDataModeActive,
    permissions,
    hasSearchDataModeCompatibleProvider,
}: Props) => {
    const [showAbout, setShowAbout] = React.useState(false);
    const [isOpen, setIsOpen] = React.useState(false);
    const [showRedoPageStateModal, setShowRedoPageStateModal] = React.useState(false);
    const [redoPageStateMessage, setRedoPageStateMessage] = React.useState("");
    const [showImportBlueprintTranslationsModal, setShowImportBlueprintTranslationsModal] = React.useState(false);
    const [importBlueprintTranslationsMessage, setImportBlueprintTranslationsMessage] = React.useState("");

    const clickRedoPageState = async () => {
        setShowRedoPageStateModal(true);
        const result = await redoPageState();
        setRedoPageStateMessage(result.message);
    };
    const clickImportBlueprintTranslations = async () => {
        setShowImportBlueprintTranslationsModal(true);
        generateBlueprintTranslations()
            .then(response => {
                setImportBlueprintTranslationsMessage(`${response.message}`);
            })
            .catch(error => {
                setImportBlueprintTranslationsMessage(TS("An error occurred importing the blueprint translations"));
            });
    };

    return (
        <>
            <OverflowMenu
                position="end"
                onOpen={() => setIsOpen(true)}
                onClose={() => setIsOpen(false)}
                buttonProps={{
                    css: css`
                        height: 32px;
                        padding: 0 16px;
                        background-color: transparent;
                        border: 0;
                        border-radius: 0;
                        margin-top: 1px;

                        &:hover {
                            background-color: ${shellTheme.colors.custom.activeBackground};
                        }

                        &:focus {
                            outline: none;
                            i {
                                transform: rotate(${isOpen ? "120deg" : "0deg"});
                            }
                        }
                    `,
                }}
                customIcon={<AxiomIcon src="gear" size={20} />}
                cssOverrides={{
                    menuItem: menuItemStyles,
                    wrapper: wrapperStyles,
                }}
                maxHeight="400px"
                data-test-selector="expand_shellSettings"
                _width={235}
            >
                <OverflowMenu
                    position="before"
                    yPosition="top"
                    buttonProps={{
                        css: css`
                            height: 32px;
                            padding: 0 16px;
                            background-color: transparent;
                            border: 0;
                            border-radius: 0;
                            margin-top: 1px;
                            color: black;

                            &:hover {
                                background-color: ${shellTheme.colors.custom.activeBackground};
                            }

                            &:focus {
                                outline: none;
                            }
                        `,
                    }}
                    customIcon={
                        <ArrowContainerStyle>
                            <Clickable data-test-selector="shellSettings_showContentManagement">
                                {TS("Content Management")}
                            </Clickable>
                            <ArrowRight width={10} />
                        </ArrowContainerStyle>
                    }
                    cssOverrides={{
                        menuItem: menuItemStyles,
                        wrapper: wrapperContentManagementStyles,
                    }}
                    maxHeight="400px"
                    data-test-selector="expand_contentManagementSettings"
                    _width={235}
                >
                    <ContentManagementHeaderStyle>{TS("Content Management")}</ContentManagementHeaderStyle>
                    {permissions?.canCreatePage && (
                        <Clickable
                            data-test-selector="shellSettings_showImportExportModal"
                            onClick={showImportExportModal}
                        >
                            {TS("Import/Export Content")}
                        </Clickable>
                    )}
                    {permissions?.canRestoreContent && (
                        <Clickable
                            data-test-selector="shellSettings_showRestoreContentModal"
                            onClick={showRestoreContentModal}
                        >
                            {TS("Sitewide Content Reset")}
                        </Clickable>
                    )}
                    <Clickable data-test-selector="shellSettings_redoPageState" onClick={clickRedoPageState}>
                        {TS("Redo Page State")}
                    </Clickable>
                    <Clickable
                        data-test-selector="shellSettings_importBlueprintTranslations"
                        onClick={clickImportBlueprintTranslations}
                    >
                        {TS("Import Blueprint Translations")}
                    </Clickable>
                </OverflowMenu>
                {enableMobileCms && (
                    <Clickable
                        data-test-selector="shellSettings_switchCms"
                        onClick={() =>
                            toggleMobileCmsMode(mobileCmsModeActive ? homePageId : mobileHomePageId, router.navigate)
                        }
                    >
                        {mobileCmsModeActive ? TS("Switch to Desktop CMS") : TS("Switch to Mobile CMS")}
                    </Clickable>
                )}
                {permissions?.canUseSearchDataMode && hasSearchDataModeCompatibleProvider && (
                    <Clickable
                        data-test-selector="shellSettings_searchDataMode"
                        onClick={() => toggleSearchDataModeActive()}
                    >
                        {searchDataModeActive ? TS("Disable Search Data Mode") : TS("Enable Search Data Mode")}
                    </Clickable>
                )}
                <Clickable data-test-selector="shellSettings_showAbout" onClick={() => setShowAbout(true)}>
                    {TS("About")}
                </Clickable>
                <Clickable data-test-selector="shellSettings_logOut" onClick={logOut}>
                    {TS("Log Out")}
                </Clickable>
            </OverflowMenu>
            <Modal isOpen={showAbout} headline={TS("About")} isCloseable handleClose={() => setShowAbout(false)}>
                <About />
            </Modal>
            <Modal
                sizeVariant="small"
                isOpen={showRedoPageStateModal}
                headline={TS("Redo Page State")}
                handleClose={() => {
                    setShowRedoPageStateModal(false);
                    setRedoPageStateMessage("");
                }}
            >
                {redoPageStateMessage ? (
                    <>{redoPageStateMessage}</>
                ) : (
                    <StyledWrapper
                        css={css`
                            display: flex;
                            height: 100px;
                            justify-content: center;
                            align-items: center;
                        `}
                    >
                        <LoadingSpinner />
                    </StyledWrapper>
                )}
            </Modal>
            <Modal
                sizeVariant="small"
                isOpen={showImportBlueprintTranslationsModal}
                headline={TS("Import Blueprint Translations")}
                handleClose={() => {
                    setShowImportBlueprintTranslationsModal(false);
                    setImportBlueprintTranslationsMessage("");
                }}
            >
                {importBlueprintTranslationsMessage ? (
                    <>{importBlueprintTranslationsMessage}</>
                ) : (
                    <StyledWrapper
                        css={css`
                            display: flex;
                            height: 100px;
                            justify-content: center;
                            align-items: center;
                        `}
                    >
                        <LoadingSpinner />
                    </StyledWrapper>
                )}
            </Modal>
        </>
    );
};

export default connect(mapStateToProps, mapDispatchToProps)(withRouter(HeaderGear));
