import _ from 'lodash';
import React from 'react';

import PureRenderMixin from 'react-addons-pure-render-mixin';
import { block } from 'bem-cn';
import { Spin } from 'lego-on-react';
import StoreMixin from 'lib/StoreMixin';

import ResourcesStore from 'stores/Resources';
import PermissionStore from 'stores/Permissions';
import ConfigStore from 'stores/Config';
import ResourcesActions from 'actions/Resources';
import ModalActions from 'actions/Modal';

import { i18n } from 'lib/i18n';
import notify from 'services/notify';

import { Warning } from 'components/Icon';
import RequestTableRow from './RequestTableRow';

import './index.css';

const bRequestList = block('request-list');
const bTable = block('table');

export default React.createClass({

    mixins: [StoreMixin, PureRenderMixin],

    getStoreState() {
        const { serviceSlug, resourceId } = this.props;
        const { requests, roles } = ResourcesStore.getResource(serviceSlug, resourceId);
        const editable = PermissionStore.contains('can_change_relations',
            { path: ['resource', serviceSlug, resourceId] }, true);

        return { requests, roles, editable };
    },

    componentDidMount() {
        this.subscribe([ResourcesStore, PermissionStore, ConfigStore]);
    },

    componentWillUnmount() {
        this._unmounted = true;
    },

    _getText(key, params) {
        const { serviceSlug } = this.props;

        return i18n(`resource_page.${serviceSlug}.${key}`, params) || i18n(`resource_page.default.${key}`, params);
    },

    _handleRequest(userId, action) {
        if (this.state.busy) {
            return;
        }

        const { serviceSlug, resourceId } = this.props;
        const data = {
            user_id: userId,
            service: serviceSlug,
            resource_id: resourceId,
        };

        this.setState({ busy: true });

        ResourcesActions[`${action}Request`](data)
            .then(response => {
                if (response && response.errors) {
                    notify(response.errors.get('_common'), 'error');
                } else {
                    notify(this._getText(`${action}_request_success`), 'success');
                }
            })
            .catch(() => {
                notify(this._getText(`${action}_request_error`), 'error');
            })
            .finally(() => {
                if (!this._unmounted) {
                    this.setState({ busy: false });
                }
            });
    },

    _confirmRequestWarning() {
        return [
            <p
                key="warning"
                className="dialog-form__warning"
            >
                <Warning className="dialog-form__icon dialog-form__icon_warning" />
                {this._getText('confirm_request_warning_header')}
            </p>,
            this._getText('confirm_request_warning_message'),
        ];
    },

    _confirmRequest(id, external) {
        let promise = Promise.resolve();

        if (external) {
            promise = new Promise(resolve => {
                ModalActions.confirm({
                    title: this._getText('confirm_request_warning_title'),
                    confirmButtonText: i18n('common.action.confirm'),
                    message: this._confirmRequestWarning(),
                    onConfirm: () => resolve(),
                });
            });
        }

        promise.then(() => {
            this._handleRequest(id, 'confirm');
        });
    },

    _denyRequest(id) {
        this._handleRequest(id, 'deny');
    },

    render() {
        const { requests, roles, editable, busy } = this.state;

        return (
            <div className={bRequestList.state({ busy })}>
                <table className={bTable()}>
                    <thead className={bTable('header')}>
                        <tr className={bTable('header-row')}>
                            <td className={bTable('cell')}>
                                {this._getText('fields.user')}
                            </td>
                            <td className={bTable('cell')}>
                                {this._getText('fields.accessory')}
                            </td>
                            <td className={bTable('cell')}>
                                {this._getText('fields.role')}
                            </td>
                            <td className={bTable('cell')} />
                        </tr>
                    </thead>
                    <tbody className={bTable('body')}>
                        {requests.map(({ object, name, comment }) => (
                            <RequestTableRow
                                key={`request-${object.id}`}
                                userId={object.id}
                                avatarId={object.avatar_id}
                                name={object.name}
                                position={object.position}
                                external={object.external}
                                role={(_.find(roles, role => role.slug === name) || {}).name || name}
                                comment={comment}
                                editable={editable}
                                onConfirm={this._confirmRequest}
                                onDeny={this._denyRequest}
                                getText={this._getText}
                            />
                        ))}
                    </tbody>
                </table>
                <Spin
                    progress={busy}
                    size="m"
                    position="center"
                />
            </div>
        );
    },
});
