import React, {Fragment} from 'react';
import {Link} from 'framework7-react';
import { Device } from '../../web-apps/apps/common/mobile/utils/device';

const EditorUIController = () => {
    return null
};

EditorUIController.isSupportEditFeature = () => {
    return true;
};

/**

This is the file where the magic happens.
Try to figure out a working version from a both the old commits
and my hunches from hacking around in the old webapp editor

https://github.com/ONLYOFFICE/web-apps/commit/7c72e8cb1b3e06ac72b0e7156d33b8a8d3206dc4
*/

EditorUIController.toolbarOptions = {
    // This implementation is likely incomplete, since wsProps,  focusOn,  isShapeLocked are currently ununsed
    // and wsProps was specifically added to the options given to getEditOptions in order to handle protection
    // https://github.com/ONLYOFFICE/web-apps/commit/1508b2ee641e9f8e633628dfe7e76bfe8a2f82b2#diff-9358b4112e282a95c6f9568c509cfa89d866b92701dfd5d347349ad85971e53eR31
    // wsProps contains severals properties that are true if specific protection is enabled
    getEditOptions: (options) => {
        // console.log('EditorUIController.toolbarOptions.getEditOptions' ,options);
        return (
            <Fragment>
                <Link className={options.disabled && 'disabled'} id='btn-edit' icon='icon-edit-settings' href={false} onClick={() => options.onEditClick()}></Link>
                <Link className={options.disabled && 'disabled'} id='btn-add' icon='icon-plus' href={false} onClick={() => options.onAddClick()}></Link>
            </Fragment>
        );
    },

    getUndoRedo: (options) => {
        return (
            <Fragment>
                <Link icon='icon-undo' className={options.disabledUndo && 'disabled'} onClick={() => options.onUndoClick()}></Link>
                <Link icon='icon-redo' className={options.disabledRedo && 'disabled'} onClick={() => options.onRedoClick()}></Link>
            </Fragment>
        );
    }
}

EditorUIController.initCellInfo = (props) => {
    // console.log('EditorUIController.initCellInfo', props);

    const storeFocusObjects = props.storeFocusObjects;
    const storeCellSettings = props.storeCellSettings;
    const storeTextSettings = props.storeTextSettings;
    const storeChartSettings = props.storeChartSettings;
    const api = Common.EditorApi.get();

    storeFocusObjects.intf = EditorUIController.Intf(storeFocusObjects);

    api.asc_registerCallback('asc_onSelectionChanged', cellInfo => {
        // console.log("asc_onSelectionChanged",cellInfo);
        // console.log('storeFocusObjects', {
        //     'isLocked':         storeFocusObjects.isLocked,
        //     'isLockedText':     storeFocusObjects.isLockedText,
        //     'isLockedShaped':   storeFocusObjects.isLockedShaped,
        //     'editFormulaMode':  storeFocusObjects.editFormulaMode,
        //     'isEditCell':       storeFocusObjects.isEditCell,
        //     'functionDisabled': storeFocusObjects.functionDisabled
        // });

        // TODO Not sure if good idea or not but maybe we should check if cell is locked
        // In that case, get the protected ranges and see if we should allow to select
        // that cell.
        // const api = Common.EditorApi.get();

        // console.log({
        //     'api.asc_isProtectedSheet':         api.asc_isProtectedSheet(),
        //     'api.asc_checkLockedCells':         api.asc_checkLockedCells(),
        //     'shouldCheckProtectedRanges':   api.asc_isProtectedSheet() && api.asc_checkLockedCells(),
        //     'iscelllocked':                 api.asc_isProtectedSheet() && api.asc_checkLockedCells() ? api.asc_checkProtectedRange() : false
        // });

        // This changes the type of the selected focus to show different edit views.
        // The edit views needs the focusOn value to be set.
        // Since this change was made after the mobile editor has been made private, I'm not
        // sure if this is the way to know if the selection is a cell or an object but this
        // seems to work. this old commit shows how changeFocus used to work:
        // https://github.com/ONLYOFFICE/web-apps/commit/050c03096243448b040fc676cd350c090a1a8c59
        const isObject = cellInfo.asc_getSelectionType() !== Asc.c_oAscSelectionType.RangeCells;
        storeFocusObjects.changeFocus(isObject);

        storeFocusObjects.resetCellInfo(cellInfo);
        storeCellSettings.initCellSettings(cellInfo);
        storeTextSettings.initTextSettings(cellInfo);

        let selectedObjects = Common.EditorApi.get().asc_getGraphicObjectProps();

        if(selectedObjects.length) {
            storeFocusObjects.resetFocusObjects(selectedObjects);

            // Chart Settings

            if (storeFocusObjects.chartObject) {
                storeChartSettings.updateChartStyles(api.asc_getChartPreviews(storeFocusObjects.chartObject.get_ChartProperties().getType()));
            }
        }
    });
}

EditorUIController.initFonts = (props) => {
    // console.log('EditorUIController.initFonts', storeTextSettings);

    const storeCellSettings = props.storeCellSettings;
    const storeTextSettings = props.storeTextSettings;
    const api = Common.EditorApi.get();
    api.asc_registerCallback('asc_onInitEditorFonts', (fonts, select) => {
        // console.log('asc_onInitEditorFonts', fonts, select);
        storeCellSettings.initEditorFonts(fonts, select);
        storeTextSettings.initEditorFonts(fonts, select);
    });

    // Maybe this go here ?
    api.asc_registerCallback('asc_onEditorSelectionChanged', fontObj => {
        // console.log(fontObj)
        storeCellSettings.initFontInfo(fontObj);
        storeTextSettings.initFontInfo(fontObj);
    });
};
EditorUIController.initEditorStyles = (storeCellSettings) => {
    // console.log('EditorUIController.initEditorStyles', storeCellSettings);

    const api = Common.EditorApi.get();
    api.asc_registerCallback('asc_onInitEditorStyles', styles => {
        storeCellSettings.initCellStyles(styles);
    });
}

EditorUIController.initThemeColors = () => {
    // console.log('EditorUIController.initThemeColors');
    const api = Common.EditorApi.get();
    api.asc_registerCallback('asc_onSendThemeColors', (colors, standart_colors) => {
        // console.log('asc_onSendThemeColors', colors, standart_colors);
        Common.Utils.ThemeColor.setColors(colors, standart_colors);
    });
}

EditorUIController.ContextMenu = {
    // https://github.com/ONLYOFFICE/web-apps/commit/588a7f03863ebf9ec3251a36decc8b4e280dda59
    mapMenuItems: (contextMenu) => {
        // console.log('EditorUIController.ContextMenu.mapMenuItems', contextMenu);

        if ( !Common.EditorApi ) return [];

        const { t } = contextMenu.props;
        const _t = t("ContextMenu", { returnObjects: true });

        const { canViewComments } = contextMenu.props;

        const api = Common.EditorApi.get();
        const cellinfo = api.asc_getCellInfo();

        const itemsIcon = [];
        const itemsText = [];

        let iscellmenu, isrowmenu, iscolmenu, isallmenu, ischartmenu, isimagemenu, istextshapemenu, isshapemenu, istextchartmenu;
        let iscelllocked = cellinfo.asc_getLocked();
        const seltype = cellinfo.asc_getSelectionType();
        const xfs = cellinfo.asc_getXfs();
        const isComments = cellinfo.asc_getComments().length > 0; //prohibit adding multiple comments in one cell;

        // Check if the individual cell is locked
        // This code is taken from ./web-apps/apps/spreadsheeteditor/main/app/controller/Main.js
        // It seems that api.asc_checkProtectedRange() returns null if the cell is locked.
        iscelllocked = api.asc_isProtectedSheet() && api.asc_checkLockedCells() ? api.asc_checkProtectedRange() : false;
        iscelllocked = iscelllocked === null ? true : false;

        const { isDisconnected } = contextMenu.props;

        switch (seltype) {
            case Asc.c_oAscSelectionType.RangeCells:     iscellmenu  = true;     break;
            case Asc.c_oAscSelectionType.RangeRow:       isrowmenu   = true;     break;
            case Asc.c_oAscSelectionType.RangeCol:       iscolmenu   = true;     break;
            case Asc.c_oAscSelectionType.RangeMax:       isallmenu   = true;     break;
            case Asc.c_oAscSelectionType.RangeImage:     isimagemenu = true;     break;
            case Asc.c_oAscSelectionType.RangeShape:     isshapemenu = true;     break;
            case Asc.c_oAscSelectionType.RangeChart:     ischartmenu = true;     break;
            case Asc.c_oAscSelectionType.RangeChartText: istextchartmenu = true; break;
            case Asc.c_oAscSelectionType.RangeShapeText: istextshapemenu = true; break;
        }

        if (!iscelllocked && (isimagemenu || isshapemenu || ischartmenu || istextshapemenu || istextchartmenu)) {
            api.asc_getGraphicObjectProps().every((object) => {
                if (object.asc_getObjectType() == Asc.c_oAscTypeSelectElement.Image) {
                    iscelllocked = object.asc_getObjectValue().asc_getLocked();
                }
                return !iscelllocked;
            });
        }

        if (iscelllocked || api.isCellEdited) {
            itemsIcon.push({
                event: 'copy',
                icon: 'icon-copy'
            });

        } else {
            itemsIcon.push({
                event: 'cut',
                icon: 'icon-cut'
            });
            itemsIcon.push({
                event: 'copy',
                icon: 'icon-copy'
            });
            itemsIcon.push({
                event: 'paste',
                icon: 'icon-paste'
            });
            itemsText.push({
                caption: _t.menuDelete,
                event: 'del'
            });

            if (isimagemenu || isshapemenu || ischartmenu ||
                istextshapemenu || istextchartmenu) {
                itemsText.push({
                    caption: _t.menuEdit,
                    event: 'edit'
                });
            } else {
                if (iscolmenu || isrowmenu) {
                    itemsText.push({
                        caption: _t.menuHide,
                        event: 'hide'
                    });
                    itemsText.push({
                        caption: _t.menuShow,
                        event: 'show'
                    });
                } else if (iscellmenu) {
                    if (!iscelllocked) {
                        itemsText.push({
                            caption: _t.menuCell,
                            event: 'edit'
                        });
                    }

                    if (cellinfo.asc_getMerge() == Asc.c_oAscMergeOptions.None) {
                        itemsText.push({
                            caption: _t.menuMerge,
                            event: 'merge'
                        });
                    }

                    if (cellinfo.asc_getMerge() == Asc.c_oAscMergeOptions.Merge) {
                        itemsText.push({
                            caption: _t.menuUnmerge,
                            event: 'unmerge'
                        });
                    }

                    itemsText.push(
                        xfs.asc_getWrapText() ?
                            {
                                caption: _t.menuUnwrap,
                                event: 'unwrap'
                            } :
                            {
                                caption: _t.menuWrap,
                                event: 'wrap'
                            });

                    if (cellinfo.asc_getHyperlink() && !cellinfo.asc_getMultiselect()) {
                        itemsText.push({
                            caption: _t.menuOpenLink,
                            event: 'openlink'
                        });
                        itemsText.push({
                            caption: _t.menuEditLink,
                            event: 'editlink'
                        });
                    } else if (!cellinfo.asc_getHyperlink() && !cellinfo.asc_getMultiselect() &&
                        !cellinfo.asc_getLockText() && !!cellinfo.asc_getText()) {
                        itemsText.push({
                            caption: _t.menuAddLink,
                            event: 'addlink'
                        });
                    }
                }

                itemsText.push({
                    caption: api.asc_getSheetViewSettings().asc_getIsFreezePane() ? _t.menuUnfreezePanes : _t.menuFreezePanes,
                    event: 'freezePanes'
                });

            }

            if (canViewComments) {
                if (isComments) {
                    itemsText.push({
                        caption: _t.menuViewComment,
                        event: 'viewcomment'
                    });
                } else if (iscellmenu) {
                    itemsText.push({
                        caption: _t.menuAddComment,
                        event: 'addcomment'
                    });
                }
            }
        }

        // The below is guesswork on how Onlyoffice should handle itself with locked cells.
        if(iscelllocked) {
            if (iscellmenu && cellinfo.asc_getHyperlink()) {
                itemsText.push({
                    caption: _t.menuOpenLink,
                    event: 'openlink'
                });
            }

            const {isRestrictedEdit, canViewComments, canCoAuthoring, canComments, isResolvedComments, isVersionHistoryMode} = contextMenu.props;
            const comments = cellinfo.asc_getComments(); //prohibit adding multiple comments in one cell;

            if(!isDisconnected && !isVersionHistoryMode) {
                if (canViewComments && comments && comments.length && ((!isSolvedComment && !isResolvedComments) || isResolvedComments)) {
                    itemsText.push({
                        caption: _t.menuViewComment,
                        event: 'viewcomment'
                    });
                }

                if (iscellmenu && !api.isCellEdited && isRestrictedEdit && canCoAuthoring && canComments && comments && comments.length<1) {
                    itemsText.push({
                        caption: _t.menuAddComment,
                        event: 'addcomment'
                    });
                }
            }
        }

        if ( Device.phone && itemsText.length > 2 ) {
            contextMenu.extraItems = itemsText.splice(2,itemsText.length, {
                caption: _t.menuMore,
                event: 'showActionSheet'
            });
        }

        return itemsIcon.concat(itemsText);
    } ,
    // https://github.com/ONLYOFFICE/web-apps/commit/588a7f03863ebf9ec3251a36decc8b4e280dda59
    handleMenuItemClick: (contextMenu, action) => {
        // console.log('EditorUIController.ContextMenu.handleMenuItemClick', contextMenu, action);

        const api = Common.EditorApi.get();
        const info = api.asc_getCellInfo();
        switch (action) {
            case 'addcomment':
                Common.Notifications.trigger('addcomment');
                return true;
            case 'del':
                api.asc_emptyCells(Asc.c_oAscCleanOptions.All);
                return true;
            case 'wrap':
                api.asc_setCellTextWrap(true);
                return true;
            case 'unwrap':
                api.asc_setCellTextWrap(false);
                return true;
            case 'edit':
                setTimeout(() => {
                    contextMenu.props.openOptions('edit');
                }, 0);
                return true;
            case 'merge':
                if (api.asc_mergeCellsDataLost(Asc.c_oAscMergeOptions.Merge)) {
                    setTimeout(() => {
                        f7.dialog.confirm(_t.warnMergeLostData, _t.notcriticalErrorTitle, () => {
                            api.asc_mergeCells(Asc.c_oAscMergeOptions.Merge);
                        });
                    }, 0);
                } else {
                    api.asc_mergeCells(Asc.c_oAscMergeOptions.Merge);
                }
                return true;
            case 'unmerge':
                api.asc_mergeCells(Asc.c_oAscMergeOptions.None);
                return true;
            case 'hide':
                api[info.asc_getSelectionType() == Asc.c_oAscSelectionType.RangeRow ? 'asc_hideRows' : 'asc_hideColumns']();
                return true;
            case 'show':
                api[info.asc_getSelectionType() == Asc.c_oAscSelectionType.RangeRow ? 'asc_showRows' : 'asc_showColumns']();
                return true;
            case 'addlink':
                setTimeout(() => {
                    contextMenu.props.openOptions('add', 'link');
                }, 400)
                return true;
            case 'editlink':
                setTimeout(() => {
                    contextMenu.props.openOptions('edit', 'link');
                }, 400)
                return true;
            case 'freezePanes':
                api.asc_freezePane();
                break;
        }

        return false;
    },
};

// This objects holds the mysterious functions in focusObjects.js inside the intf object
// These for now are based on the latest valid implementation from the mobile editor
// https://github.com/ONLYOFFICE/web-apps/commit/7c72e8cb1b3e06ac72b0e7156d33b8a8d3206dc4#diff-a9931472dbd29941dda676251382f80122ff2f08aadc849684e08b505d174bf2
EditorUIController.Intf = function (storeFocusObjects) {
    var obj = {};

    obj.getSelections = () => {
        const _selections = [];

        let isCell, isRow, isCol, isAll, isChart, isImage, isTextShape, isShape, isTextChart,
            selType             = storeFocusObjects._cellInfo.asc_getSelectionType(),
            isObjLocked         = false;

        switch (selType) {
            case Asc.c_oAscSelectionType.RangeCells:    isCell  = true; break;
            case Asc.c_oAscSelectionType.RangeRow:      isRow   = true; break;
            case Asc.c_oAscSelectionType.RangeCol:      isCol   = true; break;
            case Asc.c_oAscSelectionType.RangeMax:      isAll   = true; break;
            case Asc.c_oAscSelectionType.RangeImage:    isImage = true; break;
            case Asc.c_oAscSelectionType.RangeShape:    isShape = true; break;
            case Asc.c_oAscSelectionType.RangeChart:    isChart = true; break;
            case Asc.c_oAscSelectionType.RangeChartText:isTextChart = true; break;
            case Asc.c_oAscSelectionType.RangeShapeText: isTextShape = true; break;
        }

        if (isImage || isShape || isChart) {
            isImage = isShape = isChart = false;
            let has_chartprops = false;
            let selectedObjects = Common.EditorApi.get().asc_getGraphicObjectProps();

            for (let i = 0; i < selectedObjects.length; i++) {
                if (selectedObjects[i].asc_getObjectType() == Asc.c_oAscTypeSelectElement.Image) {
                    const elValue = selectedObjects[i].asc_getObjectValue();
                    isObjLocked = isObjLocked || elValue.asc_getLocked();
                    const shapeProps = elValue.asc_getShapeProperties();

                    if (shapeProps) {
                        if (shapeProps.asc_getFromChart()) {
                            isChart = true;
                        } else {
                            isShape = true;

                        }
                    } else if (elValue.asc_getChartProperties()) {
                        isChart = true;
                        has_chartprops = true;
                    } else {
                        isImage = true;
                    }
                }
            }
        } else if (isTextShape || isTextChart) {
            const selectedObjects = Common.EditorApi.get().asc_getGraphicObjectProps();
            let isEquation = false;

            for (var i = 0; i < selectedObjects.length; i++) {
                const elType = selectedObjects[i].asc_getObjectType();
                if (elType == Asc.c_oAscTypeSelectElement.Image) {
                    const value = selectedObjects[i].asc_getObjectValue();
                    isObjLocked = isObjLocked || value.asc_getLocked();
                } else if (elType == Asc.c_oAscTypeSelectElement.Paragraph) {
                } else if (elType == Asc.c_oAscTypeSelectElement.Math) {
                    isEquation = true;
                }
            }
        }
        if (isChart || isTextChart) {
            _selections.push('chart');

            if (isTextChart) {
                _selections.push('text');
            }
        } else if ((isShape || isTextShape) && !isImage) {
            _selections.push('shape');

            if (isTextShape) {
                _selections.push('text');
            }
        } else if (isImage) {
            _selections.push('image');

            if (isShape) {
                _selections.push('shape');
            }
        } else {
            _selections.push('cell');

            if (storeFocusObjects._cellInfo.asc_getHyperlink()) {
                _selections.push('hyperlink');
            }
        }
        return _selections;
    }

    obj.getShapeObject = () => {
        const shapes = [];
        for (let object of storeFocusObjects._focusObjects) {
            if (object.get_ObjectType() === Asc.c_oAscTypeSelectElement.Image) {
                if (object.get_ObjectValue() && object.get_ObjectValue().get_ShapeProperties()) {
                    shapes.push(object);
                }
            }
        }
        if (shapes.length > 0) {
            const object = shapes[shapes.length - 1]; // get top
            return object.get_ObjectValue();
        } else {
            return undefined;
        }
    }

    obj.getImageObject = () => {
        const images = [];
        for (let object of storeFocusObjects._focusObjects) {
            if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Image) {
                images.push(object);
            }
        }
        if (images.length > 0) {
            const object = images[images.length - 1]; // get top
            return object.get_ObjectValue();
        } else {
            return undefined;
        }
    }

    obj.getChartObject = () => {
        const charts = [];
        for (let object of storeFocusObjects._focusObjects) {
            if (object.get_ObjectType() === Asc.c_oAscTypeSelectElement.Image) {
                if (object.get_ObjectValue() && object.get_ObjectValue().get_ChartProperties()) {
                    charts.push(object);
                }
            }
        }
        if (charts.length > 0) {
            const object = charts[charts.length - 1]; // get top table
            return object.get_ObjectValue();
        } else {
            return undefined;
        }
    }

    return obj;
}

export default EditorUIController;
