import React from 'react';
import block from 'bem-cn';
import { Select } from 'lego-on-react';
import { i18n } from 'i18n2';
import directory from 'api2/directory';
import notify from 'lib2/notify';
import Modal from 'components2/Modal';
import SearchBox from 'components2/SearchBox';
import Form from 'components2/Form';

import './index.css';

const RelationTargetType = {
    default: 'user',
    alice_b2b: 'all',
};

const b = block('resource-relations-modal');

function toSelectItems(itemMap = {}) {
    return Object.entries(itemMap).map(([val, text]) => ({ val, text }));
}

function toRelation(item) {
    let { object, object_id: id, object_type: type, name } = item;

    return {
        object_id: (object && object.id) || id,
        object_type: type,
        name,
    };
}

export default class ResourceRelationsModal extends React.PureComponent {
    constructor(props) {
        super(props);

        this.state = {
            busy: false,
            target: null,
        };

        this._onSearchBoxChange = this._onSearchBoxChange.bind(this);
        this._onSubmit = this._onSubmit.bind(this);
        this._onCancel = this._onCancel.bind(this);
        this._onSelectChange = this._onSelectChange.bind(this);
    }

    componentWillUnmount() {
        this._unmounted = true;
    }

    _onCancel() {
        this.props.onCancel();
        this._reset();
    }

    _reset() {
        this.setState({
            target: null,
        });
    }

    _onSubmit() {
        const { onConfirm, serviceSlug, resourceId, existingRelations = [] } = this.props;
        const { target, role } = this.state;

        this.setState({
            busy: true,
        });

        let targetRelation = {
            object_type: target && target.type,
            object_id: Number(target && target.object.id),
            name: role,
        };

        let submitRelations;

        if (RelationTargetType[serviceSlug] === 'all') {
            submitRelations = directory
                // поддерживает контейнеры (group/department), без синка с IDM [DIR-8807]
                .send('PUT', `/resources/${encodeURIComponent(resourceId)}/relations/`, {
                    query: {
                        service: serviceSlug,
                    },
                    body: JSON.stringify(
                        [targetRelation]
                            .concat(existingRelations)
                            .map(toRelation)
                    ),
                });
        } else {
            // поддерживает синк с IDM, не поддерживает контейнеры (group/department) [DIR-8806]
            submitRelations = directory
                .send('POST', '/v11/relations/', {
                    body: JSON.stringify({
                        service: serviceSlug,
                        resource_id: resourceId,
                        ...targetRelation,
                    }),
                });
        }

        submitRelations
            .then(({ body, ok }) => {
                if (!ok) {
                    return notify(i18n(`backend_errors.relations.${body.code}`) ||
                        i18n('common.request_error'), 'error');
                }

                notify(this._getText('create_relation_success'), 'success');

                if (onConfirm) {
                    return onConfirm();
                }
            })
            .finally(() => {
                if (!this._unmounted) {
                    this.setState({
                        busy: false,
                    });
                }
            });
    }

    _onSearchBoxChange(items) {
        this.setState({
            target: items[0],
        });
    }

    _onSelectChange(roles) {
        this.setState({ role: roles[0] });
    }

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

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

    render() {
        const { serviceSlug, visible, cls, roles } = this.props;
        const { role, busy, target } = this.state;

        return (
            <Modal
                cls={b({}).mix(cls)}
                visible={visible}
            >
                <Modal.Title>
                    {this._getText('create_relation_modal')}
                </Modal.Title>
                <Modal.CloseButton onClick={this._onCancel} />
                <Modal.Body>
                    <Form cls={b('form')}>
                        <Form.Field name="object_id">
                            <Form.Label required>
                                {this._getText('fields.user')}
                            </Form.Label>
                            <Form.Value>
                                <SearchBox
                                    cls={b('search-box')}
                                    limit={1}
                                    values={target ? [target] : []}
                                    onChange={this._onSearchBoxChange}
                                    searchType={RelationTargetType[serviceSlug] || RelationTargetType.default}
                                />
                            </Form.Value>
                        </Form.Field>
                        <Form.Field name="name">
                            <Form.Label required>
                                {this._getText('fields.role')}
                            </Form.Label>
                            <Form.Value>
                                <Select
                                    cls={b('select')}
                                    width="max"
                                    theme="normal"
                                    size="m"
                                    name="role"
                                    type="radio"
                                    button={{ pin: 'brick-brick' }}
                                    val={role}
                                    items={toSelectItems(roles)}
                                    onChange={this._onSelectChange}
                                />
                            </Form.Value>
                        </Form.Field>
                        <Form.Actions
                            cls={b('actions')}
                            onSubmit={this._onSubmit}
                            onCancel={this._onCancel}
                            submitCaption={i18n('common.action.add')}
                            submitDisabled={!role || !target}
                        />
                    </Form>
                </Modal.Body>
                <Modal.Busy visible={busy} />
            </Modal>
        );
    }
}
