import React from 'react';
import { Link } from 'lego-on-react';
import block from 'bem-cn';
import directory from 'api2/directory';
import getService from 'lib2/getService';
import hasPermission from 'lib2/hasPermission';
import { PermissionStore, ServiceResourcesStore } from 'lib2/stores';
import getResourceLinkUrl from 'lib2/getResourceLinkUrl';
import DocTitle from 'components2/DocTitle';
import ServiceSidebar from 'components2/ServiceSidebar';
import ResourceRemoveModal from 'components2/ResourceRemoveModal';
import ResourceHeader from 'components2/ResourceHeader';
import ResourceTabs from 'components2/ResourceTabs';
import SpinOverlay from 'components2/SpinOverlay';
import NotFound from 'components2/NotFound';
import { i18n } from 'i18n2';
import './index.css';

const NonRemovableResources = {
    alice_b2b: true,
};

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

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

        const { serviceSlug, resourceId } = props;

        this.state = {
            busy: false,
            inited: Boolean(ServiceResourcesStore.get([serviceSlug, 'list', resourceId])),
            removalConfirmOpen: false,
            test: '',
            items: [],
            resource: ServiceResourcesStore.get([serviceSlug, 'list', resourceId]),
        };

        this._onPermissionStoreChange = this._onPermissionStoreChange.bind(this);
        this._onResourceStoreChange = this._onResourceStoreChange.bind(this);
        this._onRemoveClick = this._onRemoveClick.bind(this);
        this._onRemoveConfirmCancel = this._onRemoveConfirmCancel.bind(this);
    }

    componentDidMount() {
        this._permissionStoreListener = PermissionStore.onChange(this._onPermissionStoreChange);
        this._resourceStoreListener = ServiceResourcesStore.onChange(this._onResourceStoreChange);

        this._update();
    }

    componentWillUnmount() {
        this._unmounted = true;
        this._resourceStoreListener.remove();
        this._permissionStoreListener.remove();
    }

    componentDidUpdate(prevProps) {
        if (this.props.serviceSlug !== prevProps.serviceSlug) {
            this._update();
        }
    }

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

        this.setState({
            canUpdate: hasPermission('update_service_data', {
                id: serviceSlug,
                type: 'service',
            }, true),
        });
    }

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

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

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

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

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

                if (resource.ok) {
                    ServiceResourcesStore.set([serviceSlug, 'list', resourceId], resource.body);

                    this.setState({
                        inited: true,
                    });
                } else if (resource.status === 404) {
                    this.setState({
                        inited: true,
                        notFound: true,
                    });
                }
            })
            .finally(() => {
                if (!this._unmounted) {
                    this.setState({
                        busy: false,
                    });
                }
            });
    }

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

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

    _onRemoveClick() {
        this.setState({ removalConfirmOpen: true });
    }

    _onRemoveConfirmCancel() {
        this.setState({ removalConfirmOpen: false });
    }

    _renderContent() {
        const { canUpdate, removalConfirmOpen, resource, busy, inited, notFound } = this.state;
        const { serviceSlug, resourceId, tabs } = this.props;

        if (!inited) {
            return (
                <div className={b('content')}>
                    <SpinOverlay
                        progress={busy}
                        size="m"
                        position="center"
                    />
                </div>
            );
        }

        if (notFound) {
            return <NotFound />;
        }

        return (
            <div className={b('content')}>
                <ResourceHeader
                    cls={b('header', { busy: false })}
                    serviceSlug={serviceSlug}
                    busy={false}
                    resource={{
                        id: resource.id,
                        name: resource.metadata.name,
                        description: resource.metadata.description,
                    }}
                    actions={[
                        <Link
                            key="action-type-go"
                            cls={b('action', { type: 'go' })}
                            theme="normal"
                            url={getResourceLinkUrl(serviceSlug, resourceId)}
                            text={this._getText('go')}
                        />,
                        !NonRemovableResources[serviceSlug] && canUpdate && (
                            <Link
                                key="action-type-remove"
                                cls={b('action', { type: 'remove' })}
                                theme="black"
                                pseudo
                                text={this._getText('remove_resource')}
                                onClick={this._onRemoveClick}
                            />
                        ),
                    ]}
                />
                <ResourceTabs
                    visible
                    serviceSlug={serviceSlug}
                    resourceId={resourceId}
                    tabs={tabs}
                />
                <ResourceRemoveModal
                    serviceSlug={serviceSlug}
                    resourceId={resourceId}
                    onCancel={this._onRemoveConfirmCancel}
                    visible={removalConfirmOpen}
                />
            </div>
        );
    }

    render() {
        const { serviceSlug, cls } = this.props;
        const docTitle = `${getService(serviceSlug).name} @ ${i18n('common.full_main_title')}`;

        return (
            <div className={b({ slug: serviceSlug }).mix(cls)}>
                <DocTitle text={docTitle} />
                <ServiceSidebar cls={b('sidebar')} serviceSlug={serviceSlug} />
                {this._renderContent()}
            </div>
        );
    }
}
