/*
 * 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 }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _GraphPanel = require('./GraphPanel');

var _GraphPanel2 = _interopRequireDefault(_GraphPanel);

var _ActionsPanel = require('./ActionsPanel');

var _ActionsPanel2 = _interopRequireDefault(_ActionsPanel);

var debounce = require('lodash.debounce');
var React = require('react');
var Color = require('color');

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

var FontIcon = _require.FontIcon;
var Popover = _require.Popover;
var Paper = _require.Paper;
var Avatar = _require.Avatar;
var CardTitle = _require.CardTitle;

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

var muiThemeable = _require2.muiThemeable;

var MetaCacheService = require('pydio/http/meta-cache-service');
var PydioApi = require('pydio/http/api');

/**
 * Generic component for display a user and her avatar (first letters or photo)
 */

var UserAvatar = (function (_React$Component) {
    _inherits(UserAvatar, _React$Component);

    function UserAvatar(props, context) {
        _classCallCheck(this, UserAvatar);

        _React$Component.call(this, props, context);
        this.state = {
            user: null,
            avatar: null,
            graph: null
        };
    }

    UserAvatar.prototype.componentDidMount = function componentDidMount() {
        if (this.props.pydio.user && this.props.pydio.user.id === this.props.userId) {
            this.loadLocalData();
            if (!this._userLoggedObs) {
                this._userLoggedObs = this.loadLocalData.bind(this);
                this.props.pydio.observe('user_logged', this._userLoggedObs);
            }
        } else if (this.props.userType === 'user') {
            this.cache = MetaCacheService.getInstance();
            this.cache.registerMetaStream('user_public_data', 'EXPIRATION_MANUAL_TRIGGER');
            this.cache.registerMetaStream('user_public_data-rich', 'EXPIRATION_MANUAL_TRIGGER');
            this.loadPublicData(this.props.userId);
        }
    };

    UserAvatar.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
        if (!this.props.userId || this.props.userId !== nextProps.userId) {
            this.setState({ label: nextProps.userId });
        }
        if (this.props.pydio && this.props.pydio.user && this.props.pydio.user.id === nextProps.userId) {
            this.loadLocalData();
            if (!this._userLoggedObs) {
                this._userLoggedObs = this.loadLocalData.bind(this);
                this.props.pydio.observe('user_logged', this._userLoggedObs);
            }
        } else {
            if (this._userLoggedObs) {
                this.props.pydio.stopObserving('user_logged', this._userLoggedObs);
            }
            this.cache = MetaCacheService.getInstance();
            this.cache.registerMetaStream('user_public_data', 'EXPIRATION_MANUAL_TRIGGER');
            this.cache.registerMetaStream('user_public_data-rich', 'EXPIRATION_MANUAL_TRIGGER');
            this.loadPublicData(nextProps.userId);
        }
    };

    UserAvatar.prototype.componentWillUnmount = function componentWillUnmount() {
        if (this._userLoggedObs) {
            this.props.pydio.stopObserving('user_logged', this._userLoggedObs);
        }
    };

    UserAvatar.prototype.loadLocalData = function loadLocalData() {
        var pydio = this.props.pydio;

        if (!pydio.user) {
            this.setState({ label: '', avatar: null });
            return;
        }
        var userName = pydio.user.getPreference('USER_DISPLAY_NAME') || pydio.user.id;
        var avatarId = pydio.user.getPreference('avatar');
        var avatarUrl = PydioApi.getClient().buildUserAvatarUrl(pydio.user.id, avatarId);
        this.setState({
            label: userName,
            avatar: avatarUrl
        });
        if (!avatarUrl) {
            this.loadFromExternalProvider();
        }
    };

    UserAvatar.prototype.loadPublicData = function loadPublicData(userId) {

        var namespace = this.props.richCard ? 'user_public_data-rich' : 'user_public_data';
        if (this.cache.hasKey(namespace, userId)) {
            this.setState(this.cache.getByKey(namespace, userId));
            return;
        }
        PydioApi.getClient().request({
            get_action: 'user_public_data',
            user_id: userId,
            graph: this.props.richCard ? 'true' : 'false'
        }, (function (transport) {
            var data = transport.responseJSON;
            if (!data || data.error) {
                this.cache.setKey(namespace, userId, {});
                return;
            }
            var user = data.user;
            var graph = data.graph;

            var avatarUrl = undefined;
            var avatarId = user.avatar || null;
            var label = user.label || userId;
            if (!user.avatar) {
                this.loadFromExternalProvider();
            } else {
                avatarUrl = PydioApi.getClient().buildUserAvatarUrl(userId, avatarId);
            }
            this.cache.setKey(namespace, userId, {
                user: user,
                graph: graph,
                avatar: avatarUrl
            });
            this.setState({
                user: user,
                graph: graph,
                avatar: avatarUrl
            });
        }).bind(this));
    };

    UserAvatar.prototype.loadFromExternalProvider = function loadFromExternalProvider() {
        if (!this.props.pydio.getPluginConfigs("ajxp_plugin[@id='action.avatar']").get("AVATAR_PROVIDER")) {
            return;
        }
        var namespace = this.props.richCard ? 'user_public_data-rich' : 'user_public_data';
        PydioApi.getClient().request({
            get_action: 'get_avatar_url',
            userid: this.props.userId
        }, (function (transport) {
            this.setState({ avatar: transport.responseText });
        }).bind(this));
    };

    UserAvatar.prototype.render = function render() {
        var _this = this;

        var _state = this.state;
        var user = _state.user;
        var avatar = _state.avatar;
        var graph = _state.graph;
        var _props = this.props;
        var pydio = _props.pydio;
        var userId = _props.userId;
        var userType = _props.userType;
        var icon = _props.icon;
        var style = _props.style;
        var labelStyle = _props.labelStyle;
        var avatarStyle = _props.avatarStyle;
        var avatarSize = _props.avatarSize;
        var className = _props.className;
        var avatarClassName = _props.avatarClassName;
        var labelClassName = _props.labelClassName;
        var displayLabel = _props.displayLabel;
        var displayAvatar = _props.displayAvatar;
        var useDefaultAvatar = _props.useDefaultAvatar;
        var richCard = _props.richCard;
        var cardSize = _props.cardSize;
        var muiTheme = _props.muiTheme;
        var label = this.state.label;

        var userTypeLabel = undefined;
        if (user) {
            label = user.label;
        } else if (!label) {
            label = this.props.userLabel || this.props.userId;
        }

        var avatarContent = undefined,
            avatarColor = undefined,
            avatarIcon = undefined;
        if (richCard) {
            displayAvatar = useDefaultAvatar = displayLabel = true;
        }
        if (displayAvatar && !avatar && label && (!displayLabel || useDefaultAvatar)) {
            var avatarsColor = muiTheme.palette.avatarsColor;
            if (userType === 'group' || userType === 'team' || userId.indexOf('AJXP_GRP_/') === 0 || userId.indexOf('/AJXP_TEAM/') === 0) {
                avatarsColor = Color(avatarsColor).darken(0.2).toString();
            }
            var iconClassName = undefined;
            switch (userType) {
                case 'group':
                    iconClassName = 'mdi mdi-account-multiple';
                    userTypeLabel = '289';
                    break;
                case 'team':
                    iconClassName = 'mdi mdi-account-multiple-outline';
                    userTypeLabel = '603';
                    break;
                case 'remote':
                    iconClassName = 'mdi mdi-account-network';
                    userTypeLabel = '604';
                    break;
                default:
                    iconClassName = 'mdi mdi-account';
                    userTypeLabel = user ? user.external ? '589' : '590' : '288';
                    break;
            }
            if (icon) iconClassName = icon;
            if (userTypeLabel) userTypeLabel = pydio.MessageHash[userTypeLabel];
            if (richCard) {
                avatarIcon = React.createElement(FontIcon, { className: iconClassName, style: { color: avatarsColor } });
                avatarColor = '#f5f5f5';
            } else {
                avatarColor = avatarsColor;
                if (iconClassName) {
                    avatarIcon = React.createElement(FontIcon, { className: iconClassName });
                } else {
                    avatarContent = label.split(' ').map(function (word) {
                        return word[0];
                    }).join('').substring(0, 2);
                    if (avatarContent.length < 2) avatarContent = label.substring(0, 2);
                }
            }
        }
        var reloadAction = undefined,
            onEditAction = undefined,
            onMouseOver = undefined,
            onMouseOut = undefined,
            popover = undefined;
        if (richCard) {
            (function () {

                displayAvatar = true;
                style = _extends({}, style, { flexDirection: 'column' });
                avatarSize = cardSize ? cardSize : '100%';
                avatarStyle = { borderRadius: 0 };
                var localReload = function localReload() {
                    MetaCacheService.getInstance().deleteKey('user_public_data-rich', _this.props.userId);
                    _this.loadPublicData(_this.props.userId);
                };
                reloadAction = function () {
                    localReload();
                    if (_this.props.reloadAction) _this.props.reloadAction();
                };
                onEditAction = function () {
                    localReload();
                    if (_this.props.onEditAction) _this.props.onEditAction();
                };
            })();
        } else if (this.props.richOnHover) {
            (function () {

                onMouseOut = function () {
                    if (!_this.lockedBySubPopover) {
                        _this.setState({ showPopover: false });
                    }
                };
                onMouseOut = debounce(onMouseOut, 350);
                onMouseOver = function (e) {
                    _this.setState({ showPopover: true, popoverAnchor: e.currentTarget });
                    onMouseOut.cancel();
                };
                var onMouseOverInner = function onMouseOverInner(e) {
                    _this.setState({ showPopover: true });
                    onMouseOut.cancel();
                };

                var lockOnSubPopoverOpen = function lockOnSubPopoverOpen(status) {
                    _this.lockedBySubPopover = status;
                    onMouseOverInner();
                };

                popover = React.createElement(
                    Popover,
                    {
                        open: _this.state.showPopover,
                        anchorEl: _this.state.popoverAnchor,
                        onRequestClose: function (reason) {
                            if (reason !== 'clickAway' || !_this.lockedBySubPopover) {
                                _this.setState({ showPopover: false });
                            }
                        },
                        anchorOrigin: { horizontal: "left", vertical: "center" },
                        targetOrigin: { horizontal: "right", vertical: "center" },
                        useLayerForClickAway: false
                    },
                    React.createElement(
                        Paper,
                        { zDepth: 2, style: { width: 220, height: 320, overflowY: 'auto' }, onMouseOver: onMouseOverInner, onMouseOut: onMouseOut },
                        React.createElement(UserAvatar, _extends({}, _this.props, { richCard: true, richOnHover: false, cardSize: 220, lockOnSubPopoverOpen: lockOnSubPopoverOpen }))
                    )
                );
            })();
        }

        var avatarComponent = React.createElement(
            Avatar,
            {
                src: avatar,
                icon: avatarIcon,
                size: avatarSize,
                style: this.props.avatarOnly ? this.props.style : avatarStyle,
                backgroundColor: avatarColor
            },
            avatarContent
        );

        if (this.props.avatarOnly) {
            return avatarComponent;
        }

        return React.createElement(
            'div',
            { className: className, style: style, onMouseOver: onMouseOver, onMouseOut: onMouseOut },
            displayAvatar && (avatar || avatarContent || avatarIcon) && avatarComponent,
            displayLabel && !richCard && React.createElement(
                'div',
                {
                    className: labelClassName,
                    style: labelStyle },
                label
            ),
            displayLabel && richCard && React.createElement(CardTitle, { style: { textAlign: 'center' }, title: label, subtitle: userTypeLabel }),
            richCard && user && React.createElement(_ActionsPanel2['default'], _extends({}, this.state, this.props, { reloadAction: reloadAction, onEditAction: onEditAction })),
            graph && React.createElement(_GraphPanel2['default'], _extends({ graph: graph }, this.props, { userLabel: label, reloadAction: reloadAction, onEditAction: onEditAction })),
            this.props.children,
            popover
        );
    };

    return UserAvatar;
})(React.Component);

UserAvatar.propTypes = {
    /**
     * Id of the user to be loaded
     */
    userId: React.PropTypes.string.isRequired,
    /**
     * Pydio instance
     */
    pydio: React.PropTypes.instanceOf(Pydio),
    /**
     * Label of the user, if we already have it (otherwise will be loaded)
     */
    userLabel: React.PropTypes.string,
    /**
     * Type of user
     */
    userType: React.PropTypes.oneOf(['user', 'group', 'remote', 'team']),
    /**
     * Icon to be displayed in avatar
     */
    icon: React.PropTypes.string,
    /**
     * Display a rich card or a simple avatar+label chip
     */
    richCard: React.PropTypes.bool,
    /**
     * If not rich, display a rich card as popover on mouseover
     */
    richOnHover: React.PropTypes.bool,

    /**
     * Add edit action to the card
     */
    userEditable: React.PropTypes.bool,
    /**
     * Triggered after successful edition
     */
    onEditAction: React.PropTypes.func,
    /**
     * Triggered after deletion
     */
    onDeleteAction: React.PropTypes.func,
    /**
     * Triggered if a reload is required
     */
    reloadAction: React.PropTypes.func,

    /**
     * Display label element or not
     */
    displayLabel: React.PropTypes.bool,
    /**
     * Display avatar element or not
     */
    displayAvatar: React.PropTypes.bool,
    /**
     * Display only avatar
     */
    avatarOnly: React.PropTypes.bool,
    /**
     * Use default avatar
     */
    useDefaultAvatar: React.PropTypes.bool,
    /**
     * Avatar size, 40px by default
     */
    avatarSize: React.PropTypes.number,

    /**
     * Add class name to root element
     */
    className: React.PropTypes.string,
    /**
     * Add class name to label element
     */
    labelClassName: React.PropTypes.string,
    /**
     * Add class name to avatar element
     */
    avatarClassName: React.PropTypes.string,
    /**
     * Add style to root element
     */
    style: React.PropTypes.object,
    /**
     * Add style to label element
     */
    labelStyle: React.PropTypes.object,
    /**
     * Add style to avatar element
     */
    avatarStyle: React.PropTypes.object
};

UserAvatar.defaultProps = {
    displayLabel: true,
    displayAvatar: true,
    avatarSize: 40,
    userType: 'user',
    className: 'user-avatar-widget',
    avatarClassName: 'user-avatar',
    labelClassName: 'user-label'
};

exports['default'] = UserAvatar = muiThemeable()(UserAvatar);

exports['default'] = UserAvatar;
module.exports = exports['default'];
