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

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

import ResourcesStore from 'stores/Resources';
import UserStore from 'stores/Users';
import PermissionStore from 'stores/Permissions';
import ResourcesActions from 'actions/Resources';
import ModalActions from 'actions/Modal';

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

import CreateRelationForm from './CreateRelationForm';
import RelationTableRow from './RelationTableRow';

import searchIcon from '../../../static/i/search.svg';
import plusIcon from '../../../static/i/plus.svg';

import './index.css';

const bRelationList = block('relation-list');
const bTable = block('table');

const contains = (haystack, needle) => haystack && haystack.toLowerCase().indexOf(needle.toLowerCase()) !== -1;

export default React.createClass({

    mixins: [StoreMixin, PureRenderMixin],

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

        return { relations, roles, editable };
    },

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

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

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

    _shouldRender(user) {
        const { query } = this.state;

        if (!query) {
            return true;
        }

        const filterData = {
            login: [
                user.getNickname(),
                user.getEmail(),
            ],
            name: [
                user.getFirstName(),
                user.getLastName(),
                user.getMiddleName(),
            ],
        };

        if (filterData.login.some(login => contains(login, query))) {
            return true;
        }

        return query
            .split(/\s+/)
            .every(queryWord => filterData.name.some(name => contains(name, queryWord)));
    },

    _renderTable() {
        const { relations, roles, editable } = this.state;
        const userColTitle = this._getText('fields.user');
        const roleColTitle = this._getText('fields.role');

        return (
            <div className={bRelationList('table')}>
                <table className={bTable()}>
                    <thead className={bTable('header')}>
                        <tr className={bTable('header-row')}>
                            <td className={bTable('cell')}>
                                {userColTitle}
                            </td>
                            <td className={bTable('cell')}>
                                {roleColTitle}
                            </td>
                            <td className={bTable('cell')} />
                        </tr>
                    </thead>
                    <tbody className={bTable('body')}>
                        {(relations || []).map(item => {
                            const user = UserStore.get(String(item.object.id));

                            if (!this._shouldRender(user)) {
                                return null;
                            }

                            return (
                                <RelationTableRow
                                    key={`relation-${item.id}`}
                                    id={item.id}
                                    avatar={user.getAvatar()}
                                    name={user.getShortFullName()}
                                    position={user.getPosition()}
                                    role={(_.find(roles, role => role.slug === item.name) || {}).name || item.name}
                                    comment={item.comment}
                                    onClick={this._removeRelation}
                                    editable={editable}
                                />
                            );
                        })}
                    </tbody>
                </table>
            </div>
        );
    },

    _onChangeFilter(query) {
        this.setState({ query });
    },

    _removeRelation(id) {
        if (this.state.busy) {
            return;
        }

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

        this.setState({ busy: true });

        ResourcesActions.removeRelation(data)
            .then(response => {
                if (response && response.errors) {
                    notify(response.errors.get('_common'), 'error');
                } else {
                    notify(this._getText('remove_relation_success'), 'success');
                }
            })
            .catch(() => {
                notify(this._getText('remove_relation_error'), 'error');
            })
            .finally(() => {
                this.setState({ busy: false });
            });
    },

    _openCreateRelationModal() {
        const { serviceSlug, resourceId } = this.props;

        ModalActions.open({
            component: CreateRelationForm,
            closable: false,
            title: this._getText('create_relation_modal'),
            props: {
                serviceSlug,
                resourceId,
                onSubmit: ModalActions.close,
                onCancel: ModalActions.close,
            },
        });
    },

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

        return (
            <div className={bRelationList.state({ busy })}>
                <div className={bRelationList('row')}>
                    <TextInput
                        theme="normal"
                        size="m"
                        type="text"
                        pin="round-round"
                        placeholder={this._getText('filter')}
                        has-icon="true"
                        iconRight={<Icon url={searchIcon} />}
                        cls={bRelationList('filter')}
                        onChange={this._onChangeFilter}
                        text={query}
                    />
                    {editable &&
                        <Button
                            text={this._getText('create_relation')}
                            size="m"
                            theme="normal"
                            iconLeft={<Icon url={plusIcon} />}
                            cls={bRelationList('add')}
                            onClick={this._openCreateRelationModal}
                        />}
                </div>
                {this._renderTable()}
                <Spin progress={busy} size="m" position="center" />
            </div>
        );
    },

});
