import React from 'react';
import { Switch, Route } from 'react-router-dom';
import { block } from 'bem-cn';
import TabLink from 'components2/TabLink';
import ResourceRelations from 'components2/ResourceRelations';
import ResourceRequests from 'components2/ResourceRequests';

import { PermissionStore, ServiceResourceRolesStore, ServiceResourceRequestsStore } from 'lib2/stores';
import hasPermission from 'lib2/hasPermission';

import directory from 'api2/directory';
import { i18n } from 'i18n2';

const b = block('resource-tabs');

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

        this.state = {};

        this._onRolesStoreChange = this._onRolesStoreChange.bind(this);
        this._onPermissionStoreChange = this._onPermissionStoreChange.bind(this);
        this._onRequestsStoreChange = this._onRequestsStoreChange.bind(this);
        this._onRequestsUpdate = this._onRequestsUpdate.bind(this);
        this._onRelationsUpdate = this._onRelationsUpdate.bind(this);
    }

    componentDidMount() {
        this._storeListeners = [
            ServiceResourceRolesStore.onChange(this._onRolesStoreChange),
            ServiceResourceRequestsStore.onChange(this._onRequestsStoreChange),
            PermissionStore.onChange(this._onPermissionStoreChange),
        ];

        this._update();
    }

    componentWillUnmount() {
        this._storeListeners.forEach(listener => listener.remove());
    }

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

        if (serviceSlug !== prevProps.serviceSlug || resourceId !== prevProps.resourceId) {
            this._update();
        }
    }

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

        this.setState({
            requestCount: ServiceResourceRequestsStore.get([serviceSlug, resourceId, 'count']),
        });
    }

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

        this.setState({
            canChangeRelations: hasPermission('can_change_relations',
                { path: ['resource', serviceSlug, resourceId] }, true),
        });
    }

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

        this.setState({
            roles: ServiceResourceRolesStore.get([serviceSlug, resourceId, 'list']),
        });
    }

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

        directory
            .send('GET', `/v11/services/${serviceSlug}/roles/`, {
                query: {
                    resource_id: resourceId,
                },
            })
            .then(({ ok, body }) => {
                if (ok && body) {
                    const roles = body.data.reduce((acc, item) => {
                        acc[item.slug] = item.name;

                        return acc;
                    }, {});

                    ServiceResourceRolesStore.set([serviceSlug, resourceId, 'list'], roles);
                }
            });
    }

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

        directory
            .send('GET', '/v11/permissions/', {
                query: {
                    type: serviceSlug,
                    id: resourceId,
                },
            })
            .then(({ ok, body }) => {
                if (ok) {
                    PermissionStore.set(['local', 'resource', serviceSlug, resourceId], body);
                }
            });
    }

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

        if (!tabs.requests) {
            return;
        }

        let list = ServiceResourceRequestsStore.get([serviceSlug, 'list']);

        if (Array.isArray(list)) {
            ServiceResourceRequestsStore.set([serviceSlug, resourceId, 'count'], list.length);

            return;
        }

        // минимальный запрос для подсчёта заявок:
        // без fields, с минимальным per_page
        directory.send('GET', `/v11/subscription/services/${serviceSlug}/licenses/request/`, {
            query: {
                per_page: 1,
                resource_id: resourceId,
            },
        })
            .then(({ ok, body }) => {
                if (ok && body) {
                    ServiceResourceRequestsStore.set([serviceSlug, resourceId, 'count'], body.total);
                }
            });
    }

    _onRequestsUpdate() {
        this._updateRequestsCount();
    }

    _onRelationsUpdate() {
        this._updatePermissions();
    }

    _update() {
        const { tabs } = this.props;

        if (!tabs || !Object.keys(tabs).length) {
            return;
        }

        this._updateRequestsCount();
        this._updatePermissions();
        this._updateRoles();
    }

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

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

    render() {
        const { serviceSlug, resourceId, tabs } = this.props;
        const { roles, canChangeRelations, requestCount } = this.state;

        if (!tabs || !Object.keys(tabs).length) {
            return null;
        }

        return (
            <div className={b()}>
                <TabLink.Group>
                    {tabs.relations &&
                    <TabLink url={`/portal/services/${serviceSlug}/resources/${resourceId}`}>
                        {this._getText('relations_tab')}
                    </TabLink>}
                    {tabs.requests &&
                    <TabLink url={`/portal/services/${serviceSlug}/resources/${resourceId}/requests`}>
                        {this._getText('requests_tab')}
                        {requestCount &&
                        <TabLink.CounterBadge>{requestCount}</TabLink.CounterBadge>}
                    </TabLink>}
                </TabLink.Group>
                <Switch>
                    {tabs.relations &&
                    <Route exact path={`/portal/services/${serviceSlug}/resources/${resourceId}`}>
                        <TabLink.Pane>
                            <ResourceRelations
                                serviceSlug={serviceSlug}
                                resourceId={resourceId}
                                canChangeRelations={canChangeRelations}
                                roles={roles}
                                onUpdate={this._onRelationsUpdate}
                            />
                        </TabLink.Pane>
                    </Route>}
                    {tabs.requests &&
                    <Route exact path={`/portal/services/${serviceSlug}/resources/${resourceId}/requests`}>
                        <TabLink.Pane>
                            <ResourceRequests
                                serviceSlug={serviceSlug}
                                resourceId={resourceId}
                                canChangeRelations={canChangeRelations}
                                roles={roles}
                                onUpdate={this._onRequestsUpdate}
                            />
                        </TabLink.Pane>
                    </Route>}
                </Switch>
            </div>
        );
    }
}
