/*
 * Copyright 2007-2017 Charles du Jeu - Abstrium SAS <team (at) pyd.io>
 * This file is part of Pydio.
 *
 * Pydio is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Pydio is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Pydio.  If not, see <http://www.gnu.org/licenses/>.
 *
 * The latest code can be found at <https://pydio.com>.
 */

'use strict';

exports.__esModule = true;

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _NestedListItem = require('./NestedListItem');

var _NestedListItem2 = _interopRequireDefault(_NestedListItem);

var _UsersList = require('./UsersList');

var _UsersList2 = _interopRequireDefault(_UsersList);

var _RightPanelCard = require('./RightPanelCard');

var _RightPanelCard2 = _interopRequireDefault(_RightPanelCard);

var _SearchPanel = require('./SearchPanel');

var _SearchPanel2 = _interopRequireDefault(_SearchPanel);

var _Loaders = require('./Loaders');

var _Loaders2 = _interopRequireDefault(_Loaders);

var _TeamCreationForm = require('../TeamCreationForm');

var _TeamCreationForm2 = _interopRequireDefault(_TeamCreationForm);

var React = require('react');
var Pydio = require('pydio');

var _Pydio$requireLib = Pydio.requireLib('boot');

var AsyncComponent = _Pydio$requireLib.AsyncComponent;
var PydioContextConsumer = _Pydio$requireLib.PydioContextConsumer;

var _require = require('material-ui');

var Popover = _require.Popover;
var IconButton = _require.IconButton;

var _require2 = require('material-ui/styles');

var muiThemeable = _require2.muiThemeable;
var colors = _require2.colors;

/**
 * High level component to browse users, groups and teams, either in a large format (mode='book') or a more compact
 * format (mode='selector'|'popover').
 * Address book allows to create external users, teams, and also to browse trusted server directories if Federated Sharing
 * is active.
 */
var AddressBook = React.createClass({
    displayName: 'AddressBook',

    propTypes: {
        /**
         * Main instance of pydio
         */
        pydio: React.PropTypes.instanceOf(Pydio),
        /**
         * Display mode, either large (book) or small picker ('selector', 'popover').
         */
        mode: React.PropTypes.oneOf(['book', 'selector', 'popover']).isRequired,
        /**
         * Callback triggered in 'selector' mode whenever an item is clicked.
         */
        onItemSelected: React.PropTypes.func,
        /**
         * Display users only, no teams or groups
         */
        usersOnly: React.PropTypes.bool,
        /**
         * Choose various user sources, either the local directory or remote ( = trusted ) servers.
         */
        usersFrom: React.PropTypes.oneOf(['local', 'remote', 'any']),
        /**
         * Disable the search engine
         */
        disableSearch: React.PropTypes.bool,
        /**
         * Theme object passed by muiThemeable() wrapper
         */
        muiTheme: React.PropTypes.object,
        /**
         * Will be passed to the Popover object
         */
        popoverStyle: React.PropTypes.object,
        /**
         * Used as a button to open the selector in a popover
         */
        popoverButton: React.PropTypes.object,
        /**
         * Will be passed to the Popover container object
         */
        popoverContainerStyle: React.PropTypes.object,
        /**
         * Will be passed to the Popover Icon Button.
         */
        popoverIconButtonStyle: React.PropTypes.object
    },

    getDefaultProps: function getDefaultProps() {
        return {
            mode: 'book',
            usersOnly: false,
            usersFrom: 'any',
            teamsOnly: false,
            disableSearch: false
        };
    },

    getInitialState: function getInitialState() {
        var _this = this;

        var _props = this.props;
        var pydio = _props.pydio;
        var mode = _props.mode;
        var usersOnly = _props.usersOnly;
        var usersFrom = _props.usersFrom;
        var teamsOnly = _props.teamsOnly;
        var disableSearch = _props.disableSearch;

        var getMessage = function getMessage(id) {
            return _this.props.getMessage(id, '');
        };
        var confConfigs = pydio.getPluginConfigs('core.conf');

        var root = undefined;
        if (teamsOnly) {
            root = {
                id: 'teams',
                label: getMessage(568),
                childrenLoader: _Loaders2['default'].loadTeams,
                _parent: null,
                _notSelectable: true,
                actions: {
                    type: 'teams',
                    create: '+ ' + getMessage(569),
                    remove: getMessage(570),
                    multiple: true
                }
            };
            return {
                root: root,
                selectedItem: root,
                loading: false,
                rightPaneItem: null
            };
        }

        root = {
            id: 'root',
            label: getMessage(592),
            type: 'root',
            collections: []
        };
        if (usersFrom !== 'remote') {
            if (confConfigs.get('USER_CREATE_USERS')) {
                root.collections.push({
                    id: 'ext',
                    label: getMessage(593),
                    //icon:'mdi mdi-account-network',
                    itemsLoader: _Loaders2['default'].loadExternalUsers,
                    _parent: root,
                    _notSelectable: true,
                    actions: {
                        type: 'users',
                        create: '+ ' + getMessage(484),
                        remove: getMessage(582),
                        multiple: true
                    }
                });
            }
            if (!usersOnly) {
                root.collections.push({
                    id: 'teams',
                    label: getMessage(568),
                    //icon: 'mdi mdi-account-multiple',
                    childrenLoader: _Loaders2['default'].loadTeams,
                    _parent: root,
                    _notSelectable: true,
                    actions: {
                        type: 'teams',
                        create: '+ ' + getMessage(569),
                        remove: getMessage(570),
                        multiple: true
                    }
                });
            }
            if (confConfigs.get('ALLOW_CROSSUSERS_SHARING')) {
                var groupOrUsers = confConfigs.get('ADDRESSBOOK_GROUP_OR_USERS');
                if (groupOrUsers && groupOrUsers.group_switch_value) groupOrUsers = groupOrUsers.group_switch_value;else groupOrUsers = 'both';

                if (groupOrUsers === 'search') {
                    if (!disableSearch) {
                        root.collections.push({
                            id: 'search',
                            label: getMessage(583),
                            //icon:'mdi mdi-account-search',
                            type: 'search',
                            _parent: root,
                            _notSelectable: true
                        });
                    }
                } else {
                    root.collections.push({
                        id: 'AJXP_GRP_/',
                        label: getMessage(584),
                        //icon:'mdi mdi-account-box',
                        childrenLoader: groupOrUsers === 'both' || groupOrUsers === 'groups' ? _Loaders2['default'].loadGroups : null,
                        itemsLoader: groupOrUsers === 'both' || groupOrUsers === 'users' ? _Loaders2['default'].loadGroupUsers : null,
                        _parent: root,
                        _notSelectable: true
                    });
                }
            }
        }

        var ocsRemotes = pydio.getPluginConfigs('core.ocs').get('TRUSTED_SERVERS');
        if (ocsRemotes && !usersOnly && usersFrom !== 'local') {
            var remotes = JSON.parse(ocsRemotes);
            var remotesNodes = {
                id: 'remotes',
                label: getMessage(594),
                //icon:'mdi mdi-server',
                collections: [],
                _parent: root,
                _notSelectable: true
            };
            for (var k in remotes) {
                if (!remotes.hasOwnProperty(k)) continue;
                remotesNodes.collections.push({
                    id: k,
                    label: remotes[k],
                    icon: 'mdi mdi-server-network',
                    type: 'remote',
                    _parent: remotesNodes,
                    _notSelectable: true
                });
            }
            if (remotesNodes.collections.length) {
                root.collections.push(remotesNodes);
            }
        }

        return {
            root: root,
            selectedItem: mode === 'selector' ? root : root.collections[0],
            loading: false,
            rightPaneItem: null
        };
    },

    componentDidMount: function componentDidMount() {
        this.state.selectedItem && this.onFolderClicked(this.state.selectedItem);
    },

    onFolderClicked: function onFolderClicked(item) {
        var _this2 = this;

        var callback = arguments.length <= 1 || arguments[1] === undefined ? undefined : arguments[1];

        // Special case for teams
        if (item.type === 'group' && item.id.indexOf('/AJXP_TEAM/') === 0) {
            this.onUserListItemClicked(item);
            return;
        }
        this.setState({ loading: true });

        _Loaders2['default'].childrenAsPromise(item, false).then(function (children) {
            _Loaders2['default'].childrenAsPromise(item, true).then(function (children) {
                _this2.setState({ selectedItem: item, loading: false }, callback);
            });
        });
    },

    onUserListItemClicked: function onUserListItemClicked(item) {
        if (this.props.onItemSelected) {
            var uObject = new PydioUsers.User(item.id, item.label, item.type, item.group, item.avatar, item.temporary, item.external);
            if (item.trusted_server_id) {
                uObject.trustedServerId = item.trusted_server_id;
                uObject.trustedServerLabel = item.trusted_server_label;
            }
            this.props.onItemSelected(uObject);
        } else {
            this.setState({ rightPaneItem: item });
        }
    },

    onCreateAction: function onCreateAction(item) {
        this.setState({ createDialogItem: item });
    },

    closeCreateDialogAndReload: function closeCreateDialogAndReload() {
        this.setState({ createDialogItem: null });
        this.reloadCurrentNode();
    },

    onCardUpdateAction: function onCardUpdateAction(item) {
        if (item._parent && item._parent === this.state.selectedItem) {
            this.reloadCurrentNode();
        }
    },

    onDeleteAction: function onDeleteAction(parentItem, selection) {
        if (!confirm(this.props.getMessage(278))) {
            return;
        }
        switch (parentItem.actions.type) {
            case 'users':
                selection.forEach((function (user) {
                    if (this.state.rightPaneItem === user) this.setState({ rightPaneItem: null });
                    PydioUsers.Client.deleteUser(user.id, this.reloadCurrentNode.bind(this));
                }).bind(this));
                break;
            case 'teams':
                selection.forEach((function (team) {
                    if (this.state.rightPaneItem === team) this.setState({ rightPaneItem: null });
                    PydioUsers.Client.deleteTeam(team.id.replace('/AJXP_TEAM/', ''), this.reloadCurrentNode.bind(this));
                }).bind(this));
                break;
            case 'team':
                _TeamCreationForm2['default'].updateTeamUsers(parentItem, 'delete', selection, this.reloadCurrentNode.bind(this));
                break;
            default:
                break;
        }
    },

    openPopover: function openPopover(event) {
        this.setState({
            popoverOpen: true,
            popoverAnchor: event.currentTarget
        });
    },

    closePopover: function closePopover() {
        this.setState({ popoverOpen: false });
    },

    reloadCurrentNode: function reloadCurrentNode() {
        var _this3 = this;

        this.state.selectedItem.leafLoaded = false;
        this.state.selectedItem.collectionsLoaded = false;
        this.onFolderClicked(this.state.selectedItem, function () {
            if (_this3.state.rightPaneItem) {
                (function () {
                    var rPaneId = _this3.state.rightPaneItem.id;
                    var foundItem = null;
                    var leafs = _this3.state.selectedItem.leafs || [];
                    var collections = _this3.state.selectedItem.collections || [];
                    [].concat(leafs, collections).forEach(function (leaf) {
                        if (leaf.id === rPaneId) foundItem = leaf;
                    });
                    _this3.setState({ rightPaneItem: foundItem });
                })();
            }
        });
    },

    reloadCurrentAtPage: function reloadCurrentAtPage(letterOrRange) {
        this.state.selectedItem.leafLoaded = false;
        this.state.selectedItem.collectionsLoaded = false;
        if (letterOrRange === -1) {
            this.state.selectedItem.currentParams = null;
        } else if (letterOrRange.indexOf('-') !== -1) {
            this.state.selectedItem.range = letterOrRange;
        } else {
            this.state.selectedItem.range = null;
            this.state.selectedItem.currentParams = { alpha_pages: 'true', value: letterOrRange };
        }
        this.onFolderClicked(this.state.selectedItem);
    },

    reloadCurrentWithSearch: function reloadCurrentWithSearch(value) {
        if (!value) {
            this.reloadCurrentAtPage(-1);
            return;
        }
        this.state.selectedItem.leafLoaded = false;
        this.state.selectedItem.collectionsLoaded = false;
        this.state.selectedItem.currentParams = { has_search: true, value: value, existing_only: true };
        this.onFolderClicked(this.state.selectedItem);
    },

    render: function render() {
        var _this4 = this;

        var _props2 = this.props;
        var mode = _props2.mode;
        var muiTheme = _props2.muiTheme;
        var getMessage = _props2.getMessage;

        if (mode === 'popover') {

            var popoverStyle = this.props.popoverStyle || {};
            var popoverContainerStyle = this.props.popoverContainerStyle || {};
            var iconButtonStyle = this.props.popoverIconButtonStyle || {};
            var iconButton = React.createElement(IconButton, {
                style: _extends({ position: 'absolute', padding: 15, zIndex: 100, right: 0, top: 25, display: this.state.loading ? 'none' : 'initial' }, iconButtonStyle),
                iconStyle: { fontSize: 19, color: 'rgba(0,0,0,0.6)' },
                iconClassName: 'mdi mdi-book-open-variant',
                onTouchTap: this.openPopover
            });
            if (this.props.popoverButton) {
                iconButton = React.createElement(this.props.popoverButton.type, _extends({}, this.props.popoverButton.props, { onTouchTap: this.openPopover }));
            }
            return React.createElement(
                'span',
                null,
                iconButton,
                React.createElement(
                    Popover,
                    {
                        open: this.state.popoverOpen,
                        anchorEl: this.state.popoverAnchor,
                        anchorOrigin: { horizontal: 'right', vertical: 'top' },
                        targetOrigin: { horizontal: 'left', vertical: 'top' },
                        onRequestClose: this.closePopover,
                        style: _extends({ marginLeft: 20 }, popoverStyle),
                        zDepth: 2
                    },
                    React.createElement(
                        'div',
                        { style: _extends({ width: 320, height: 420 }, popoverContainerStyle) },
                        React.createElement(AddressBook, _extends({}, this.props, { mode: 'selector' }))
                    )
                )
            );
        }

        var _state = this.state;
        var selectedItem = _state.selectedItem;
        var root = _state.root;
        var rightPaneItem = _state.rightPaneItem;
        var createDialogItem = _state.createDialogItem;

        var leftColumnStyle = {
            backgroundColor: colors.grey100,
            width: 256,
            overflowY: 'auto',
            overflowX: 'hidden'
        };
        var centerComponent = undefined,
            rightPanel = undefined,
            leftPanel = undefined;

        if (selectedItem.id === 'search') {

            centerComponent = React.createElement(_SearchPanel2['default'], {
                item: selectedItem,
                title: getMessage(583, ''),
                searchLabel: getMessage(595, ''),
                onItemClicked: this.onUserListItemClicked,
                onFolderClicked: this.onFolderClicked,
                mode: mode
            });
        } else if (selectedItem.type === 'remote') {

            centerComponent = React.createElement(_SearchPanel2['default'], {
                item: selectedItem,
                params: { trusted_server_id: selectedItem.id },
                searchLabel: getMessage(595, ''),
                title: getMessage(596, '').replace('%s', selectedItem.label),
                onItemClicked: this.onUserListItemClicked,
                onFolderClicked: this.onFolderClicked,
                mode: mode
            });
        } else {

            var emptyStatePrimary = undefined;
            var emptyStateSecondary = undefined;
            var otherProps = {};
            if (selectedItem.id === 'teams') {
                emptyStatePrimary = getMessage(571, '');
                emptyStateSecondary = getMessage(572, '');
            } else if (selectedItem.id === 'ext') {
                emptyStatePrimary = getMessage(585, '');
                emptyStateSecondary = getMessage(586, '');
            } else if (selectedItem.id.indexOf('AJXP_GRP_/') === 0) {
                otherProps = {
                    showSubheaders: true,
                    paginatorType: !(selectedItem.currentParams && selectedItem.currentParams.has_search) && 'alpha',
                    paginatorCallback: this.reloadCurrentAtPage.bind(this),
                    enableSearch: !this.props.disableSearch,
                    searchLabel: getMessage(595, ''),
                    onSearch: this.reloadCurrentWithSearch.bind(this)
                };
            }

            centerComponent = React.createElement(_UsersList2['default'], _extends({
                item: selectedItem,
                onItemClicked: this.onUserListItemClicked,
                onFolderClicked: this.onFolderClicked,
                onCreateAction: this.onCreateAction,
                onDeleteAction: this.onDeleteAction,
                loading: this.state.loading,
                mode: mode,
                emptyStatePrimaryText: emptyStatePrimary,
                emptyStateSecondaryText: emptyStateSecondary,
                onTouchTap: this.state.rightPaneItem ? function () {
                    _this4.setState({ rightPaneItem: null });
                } : null
            }, otherProps));
        }
        var rightPanelStyle = _extends({}, leftColumnStyle, { transformOrigin: 'right', backgroundColor: 'white' });
        if (!rightPaneItem) {
            rightPanelStyle = _extends({}, rightPanelStyle, { transform: 'translateX(256px)', width: 0 });
        }
        rightPanel = React.createElement(_RightPanelCard2['default'], {
            pydio: this.props.pydio,
            onRequestClose: function () {
                _this4.setState({ rightPaneItem: null });
            },
            style: rightPanelStyle,
            onCreateAction: this.onCreateAction,
            onDeleteAction: this.onDeleteAction,
            onUpdateAction: this.onCardUpdateAction,
            item: rightPaneItem });
        if (mode === 'book') {
            leftPanel = React.createElement(
                MaterialUI.Paper,
                { zDepth: 0, style: _extends({}, leftColumnStyle, { zIndex: 2 }) },
                React.createElement(
                    MaterialUI.List,
                    null,
                    root.collections.map((function (e) {
                        return React.createElement(_NestedListItem2['default'], {
                            key: e.id,
                            selected: selectedItem.id,
                            nestedLevel: 0,
                            entry: e,
                            onTouchTap: this.onFolderClicked
                        });
                    }).bind(this))
                )
            );
        }

        var dialogTitle = undefined,
            dialogContent = undefined;
        if (createDialogItem) {
            if (createDialogItem.actions.type === 'users') {
                dialogTitle = getMessage(484, '');
                dialogContent = React.createElement(
                    'div',
                    { style: { height: 500 } },
                    React.createElement(AsyncComponent, {
                        namespace: 'PydioForm',
                        componentName: 'UserCreationForm',
                        zDepth: 0,
                        style: { height: 500 },
                        newUserName: "",
                        onUserCreated: this.closeCreateDialogAndReload,
                        onCancel: function () {
                            _this4.setState({ createDialogItem: null });
                        },
                        pydio: this.props.pydio
                    })
                );
            } else if (createDialogItem.actions.type === 'teams') {
                dialogTitle = getMessage(569, '');
                dialogContent = React.createElement(_TeamCreationForm2['default'], {
                    onTeamCreated: this.closeCreateDialogAndReload,
                    onCancel: function () {
                        _this4.setState({ createDialogItem: null });
                    }
                });
            } else if (createDialogItem.actions.type === 'team') {
                var selectUser = function selectUser(item) {
                    _TeamCreationForm2['default'].updateTeamUsers(createDialogItem, 'add', [item], _this4.reloadCurrentNode.bind(_this4));
                };
                dialogTitle = null;
                dialogContent = React.createElement(AddressBook, {
                    pydio: this.props.pydio,
                    mode: 'selector',
                    usersOnly: true,
                    disableSearch: true,
                    onItemSelected: selectUser
                });
            }
        }

        var style = this.props.style || {};
        return React.createElement(
            'div',
            { style: _extends({ display: 'flex', height: mode === 'selector' ? 420 : 450 }, style) },
            leftPanel,
            centerComponent,
            rightPanel,
            React.createElement(
                MaterialUI.Dialog,
                {
                    contentStyle: { width: 380, minWidth: 380, maxWidth: 380, padding: 0 },
                    bodyStyle: { padding: 0 },
                    title: React.createElement(
                        'div',
                        { style: { padding: 20 } },
                        dialogTitle
                    ),
                    actions: null,
                    modal: false,
                    open: createDialogItem ? true : false,
                    onRequestClose: function () {
                        _this4.setState({ createDialogItem: null });
                    }
                },
                dialogContent
            )
        );
    }

});

exports['default'] = AddressBook = PydioContextConsumer(AddressBook);
exports['default'] = AddressBook = muiThemeable()(AddressBook);
exports['default'] = AddressBook;
module.exports = exports['default'];
