import * as React from 'react';
import kebabCase from 'lodash/kebabCase';
import * as ToolPanelRedux from '../../../Redux/ActionsReducers/ToolPanelRedux';
import { connect } from 'react-redux';
import ArrayExtensions from '../../../Utilities/Extensions/ArrayExtensions';
import { Icon } from '../../../components/icons';
import { CheckBox } from '../../../components/CheckBox';
import DropdownButton from '../../../components/DropdownButton';
import { ALL_TOOL_PANELS, } from '../../../AdaptableState/Common/Types';
import SimpleButton from '../../../components/SimpleButton';
import { ButtonConfigure } from '../Buttons/ButtonConfigure';
import { renderWithAdaptableContext } from '../../renderWithAdaptableContext';
import { ToolPanelWrapper } from './ToolPanelWrapper';
import { ToolPanelConfigView } from './ToolPanelPopup';
import { createUuid } from '../../../components/utils/uuid';
import { ToolPanelModuleId } from '../../../Utilities/Constants/ModuleConstants';
import HelpBlock from '../../../components/HelpBlock';
import { Flex } from '../../../components/Flex';
const preventDefault = (e) => e.preventDefault();
const AdaptableToolPanelComponent = (props) => {
    const toolPanelsGlyph = React.createElement(Icon, { name: 'align-justify' });
    const moduleService = props.api.internalApi.getModuleService();
    const adaptableOptions = props.api.optionsApi.getAdaptableOptions();
    const toolPanelOptions = adaptableOptions.toolPanelOptions;
    const settingsPanelOptions = adaptableOptions.settingsPanelOptions;
    if (props.api.entitlementApi.isModuleHiddenEntitlement('ToolPanel')) {
        // do NOT show any toolPanel content if the required entitlements are missing
        return React.createElement(HelpBlock, { className: "twa:my-2 twa:p-2 twa:text-3" }, "Not enough rights");
    }
    const availableModuleItems = props.MainMenuItems.filter((menuItem) => menuItem.isVisible);
    const availableModules = availableModuleItems.map((menuItem) => menuItem.category);
    // 'Dashboard' is a special case because it's not available in the dashboard menu items, s we have to add it manually
    if (!props.api.entitlementApi.isModuleHiddenEntitlement('Dashboard')) {
        availableModules.push('Dashboard');
    }
    if (props.api.pluginsApi.getipushpullPluginApi() &&
        !props.api.entitlementApi.isModuleHiddenEntitlement('IPushPull')) {
        availableModules.push('IPushPull');
    }
    if (props.api.pluginsApi.getOpenFinPluginApi() &&
        !props.api.entitlementApi.isModuleHiddenEntitlement('OpenFin')) {
        availableModules.push('OpenFin');
    }
    const availableModuleToolPanels = ALL_TOOL_PANELS.filter((moduleToolPanel) => ArrayExtensions.ContainsItem(availableModules, moduleToolPanel));
    const onStateChange = (toolPanel, visibilityMode) => {
        if (visibilityMode === 'expanded') {
            props.onExpandToolPanel(toolPanel);
        }
        else {
            props.onCollapseToolPanel(toolPanel);
        }
    };
    const isToolPanelModuleConfigurable = props.api.internalApi
        .getModuleService()
        .getModuleById(ToolPanelModuleId)
        .isModuleEditable();
    const visibleToolPanels = [];
    const visibleToolPanelControls = (props.ToolPanels ?? []).map((toolPanelDefinition) => {
        const visibilityMode = toolPanelDefinition.VisibilityMode ?? 'collapsed';
        // 1. check if it is a custom toolPanel
        const customToolPanel = props.api.toolPanelApi.getCustomToolPanelByName(toolPanelDefinition.Name);
        if (customToolPanel) {
            visibleToolPanels.push(customToolPanel.name);
            return (React.createElement(ToolPanelWrapper, { key: customToolPanel.name, customToolPanel: customToolPanel, visibilityMode: visibilityMode, onVisibilityModeChange: (state) => onStateChange(customToolPanel.name, state) }));
        }
        // 2. check if it's an available module toolPanel
        if (availableModuleToolPanels.some((module) => module === toolPanelDefinition.Name)) {
            // assertion is safe as if just checked it in the if clause
            const moduleToolPanel = toolPanelDefinition.Name;
            visibleToolPanels.push(moduleToolPanel);
            return (React.createElement(ToolPanelWrapper, { key: moduleToolPanel, adaptableToolPanel: moduleToolPanel, visibilityMode: visibilityMode, onVisibilityModeChange: (state) => onStateChange(moduleToolPanel, state) }));
        }
    });
    const renderToolPanelDropdowns = () => {
        if (!toolPanelOptions.showToolPanelsDropdown) {
            return;
        }
        let toolpanelItems = [
            {
                clickable: false,
                label: (React.createElement("div", { key: "toolPanelTitle" },
                    ' ',
                    "\u00A0\u00A0",
                    React.createElement("b", null, 'Tool Panels'),
                    renderToolPanelConfigureButton(ToolPanelConfigView.ToolPanels))),
            },
        ];
        const isItemVisible = (panelItem) => visibleToolPanels.includes(panelItem);
        const buildDropdownButtonItem = (toolPanel, label, isVisible) => {
            return {
                id: toolPanel,
                onClick: () => {
                    onSetToolPanelVisibility(toolPanel, !isVisible);
                },
                label: (React.createElement(CheckBox, { className: "ab-dd-checkbox twa:my-0", variant: "agGrid", as: "div", value: toolPanel, key: toolPanel, checked: isVisible, onMouseDown: preventDefault }, toolPanel)),
            };
        };
        // 1. process custom tool panels
        props.api.toolPanelApi.getCustomToolPanels().forEach((customToolPanel) => {
            const customToolPanelName = customToolPanel.name;
            toolpanelItems.push(buildDropdownButtonItem(customToolPanelName, customToolPanelName, isItemVisible(customToolPanelName)));
        });
        // 2. process module tool panels
        availableModuleToolPanels.forEach((toolPanel) => {
            let moduleName = moduleService.getModuleInfoByModule(toolPanel).FriendlyName;
            toolpanelItems.push(buildDropdownButtonItem(toolPanel, moduleName, isItemVisible(toolPanel)));
        });
        // 3. sort the dropdown items alphabetically
        toolpanelItems.sort((first, second) => {
            if (first.label < second.label) {
                return -1;
            }
            if (first.label > second.label) {
                return 1;
            }
            return 0;
        });
        return (React.createElement(DropdownButton, { variant: "text", tone: "none", collapseOnItemClick: false, key: 'dropdown-toolpanels', id: 'dropdown-toolpanels', className: "ab-ToolPanel__toolbars", columns: ['label'], items: toolpanelItems, tooltip: "Manage Tool Panels" }, toolPanelsGlyph));
    };
    const renderToolPanelButtons = () => {
        const toolPanelButtons = [];
        let moduleButtons = props.ModuleButtons;
        const shouldAddSettingsPanel = settingsPanelOptions.alwaysShowInToolPanel &&
            !props.api.entitlementApi.isModuleHiddenEntitlement('SettingsPanel');
        if (shouldAddSettingsPanel && !moduleButtons.includes('SettingsPanel')) {
            moduleButtons = ['SettingsPanel', ...moduleButtons];
        }
        if (moduleButtons?.length) {
            toolPanelButtons.push(moduleButtons.map((x) => {
                let menuItem = props.MainMenuItems.find((y) => y.isVisible && y.category == x);
                if (menuItem) {
                    return (React.createElement(SimpleButton, { "data-name": menuItem.category, key: menuItem.label, icon: menuItem.icon, tone: "none", variant: "text", className: `ab-ToolPanel__Home__${kebabCase(menuItem.label)}`, tooltip: menuItem.label, onClick: () => props.onClick(menuItem.reduxAction), accessLevel: 'Full' }));
                }
            }));
        }
        return toolPanelButtons;
    };
    const renderCustomToolPanelButtons = () => {
        return props.api.toolPanelApi.getCustomToolPanelButtons().map((button) => {
            // TODO: variants of this mapping are present in several places (just search for api.internalApi.getStyleForButton() usages)
            // with the next opportunity we should abstract it
            const toolPanelContext = {
                ...props.api.internalApi.buildBaseContext(),
                toolPanelState: props.api.toolPanelApi.getToolPanelState(),
            };
            const buttonIcon = props.api.internalApi.getIconForButton(button, toolPanelContext);
            let buttonStyle = props.api.internalApi.getStyleForButton(button, toolPanelContext);
            let buttonLabel = props.api.internalApi.getLabelForButton(button, toolPanelContext);
            let buttonTooltip = props.api.internalApi.getTooltipForButton(button, toolPanelContext);
            if (button.hidden && button.hidden(button, toolPanelContext)) {
                return null;
            }
            const disabled = button.disabled && button.disabled(button, toolPanelContext);
            const buttonVariant = buttonStyle && buttonStyle.variant ? buttonStyle.variant : 'text';
            const buttonTone = buttonStyle && buttonStyle.tone ? buttonStyle.tone : 'none';
            const uniqueKey = buttonLabel ?? createUuid();
            return (React.createElement(SimpleButton, { key: uniqueKey, variant: buttonVariant, tone: buttonTone, className: `ab-ToolPanel__Home__${kebabCase(buttonLabel)} ${buttonStyle?.className || ''}`, tooltip: buttonTooltip, icon: buttonIcon, disabled: disabled, onClick: () => button.onClick(button, toolPanelContext), accessLevel: 'Full' }, buttonLabel));
        });
    };
    const onSetToolPanelVisibility = (name, checked) => {
        if (checked) {
            props.onShowToolPanel(name);
        }
        else {
            props.onHideToolPanel(name);
        }
    };
    const renderToolPanelConfigureButton = (initialTab) => {
        const moduleParams = initialTab
            ? { source: 'Other', config: { initialTab } }
            : undefined;
        return (React.createElement(ButtonConfigure, { iconSize: 16, tone: "none", className: "ab-ToolPanel__configure-button twa:ml-2", tooltip: 'Configure ToolPanels', onClick: () => {
                props.api.internalApi.showSettingsPanel('ToolPanel', moduleParams);
            } }));
    };
    const toolPanelButtons = renderToolPanelButtons();
    return (React.createElement(Flex // Cannot have the with of the parent, on windows, when you have scrollbars
    // the inner-width is smaller
    // minWidth: 'var(--ab-cmp-toolpanel__width)',
    , { 
        // the inner-width is smaller
        // minWidth: 'var(--ab-cmp-toolpanel__width)',
        className: "ab-ToolPanel twa:p-2 twa:w-full", "data-name": "adaptable-tool-panel", flexDirection: "column", justifyContent: "center" },
        React.createElement(Flex, { className: "ab-ToolPanel__header twa:p-1 twa:w-full twa:justify-start", flexDirection: "row", flexWrap: "wrap" },
            isToolPanelModuleConfigurable && renderToolPanelDropdowns(),
            toolPanelButtons,
            isToolPanelModuleConfigurable && renderToolPanelConfigureButton()),
        Boolean(props.api.toolPanelApi.getCustomToolPanelButtons().length) && (React.createElement(Flex, { className: "ab-ToolPanel__header__buttons twa:p-1 twa:justify-start", flexDirection: "row", flexWrap: "wrap" }, renderCustomToolPanelButtons())),
        visibleToolPanelControls));
};
function mapStateToProps(state) {
    return {
        ToolPanels: state.ToolPanel.ToolPanels,
        ModuleButtons: state.ToolPanel.ModuleButtons,
        MainMenuItems: state.Internal.SettingsPanelModuleEntries,
        Columns: state.Internal.Columns,
    };
}
function mapDispatchToProps(dispatch) {
    return {
        onClick: (action) => dispatch(action),
        onSetToolPanelVisibility: (toolPanels) => dispatch(ToolPanelRedux.ToolPanelSetToolPanels(toolPanels)),
        onShowToolPanel: (toolPanel) => dispatch(ToolPanelRedux.ToolPanelShowToolPanel(toolPanel)),
        onHideToolPanel: (toolPanel) => dispatch(ToolPanelRedux.ToolPanelHideToolPanel(toolPanel)),
        onExpandToolPanel: (toolPanel) => dispatch(ToolPanelRedux.ToolPanelExpandToolPanel(toolPanel)),
        onCollapseToolPanel: (toolPanel) => dispatch(ToolPanelRedux.ToolPanelCollapseToolPanel(toolPanel)),
    };
}
export const ConnectedAdaptableToolPanel = connect(mapStateToProps, mapDispatchToProps)(AdaptableToolPanelComponent);
const toolPanelContainerStyle = {
    width: '100%',
    overflow: 'auto',
};
export const getAdaptableToolPanelAgGridComponent = (adaptable) => {
    function getContainerId() {
        return 'adaptable-tool-panel_' + adaptable.adaptableOptions.adaptableId;
    }
    if (adaptable.variant === 'react') {
        return () => {
            const content = renderWithAdaptableContext(React.createElement(ConnectedAdaptableToolPanel, { api: adaptable.api, teamSharingActivated: false }), adaptable);
            return (React.createElement("div", { id: getContainerId(), className: 'ag-adaptable-panel', style: toolPanelContainerStyle }, content));
        };
    }
    return class AdaptableToolPanelAgGridComponent {
        gui;
        unmountReactRoot;
        init(params) {
            const api = adaptable.api;
            this.gui = document.createElement('div');
            this.gui.id = getContainerId();
            // preserve AG Grid naming convention
            this.gui.className = 'ag-adaptable-panel';
            Object.keys(toolPanelContainerStyle).forEach((key) => {
                //@ts-ignore
                this.gui.style[key] = toolPanelContainerStyle[key];
            });
            this.unmountReactRoot = adaptable.renderReactRoot(renderWithAdaptableContext(React.createElement(ConnectedAdaptableToolPanel, { api: api, teamSharingActivated: false }), adaptable), this.gui);
        }
        getGui() {
            if (!this.gui) {
                this.init();
            }
            return this.gui;
        }
        refresh() {
            // no refresh logic needed
        }
        destroy() {
            this.unmountReactRoot?.();
        }
    };
};
