import React from 'react';
import block from 'bem-cn';
import { Button, Icon } from 'lego-on-react';
import directory from 'api2/directory';
import getOrganization from 'lib2/getOrganization';
import { ServiceResourcesStore, PermissionStore } from 'lib2/stores';
import hasPermission from 'lib2/hasPermission';
import AvatarUnit from 'components2/AvatarUnit';
import PencilIcon from 'components/Icon/Pencil';
import ServiceResponsibleModal from 'components2/ServiceResponsibleModal';
import { i18n } from 'i18n2';

import './index.css';

const b = block('service-responsible');

const PlaceholderResponsible = {
    name: {
        first: 'xxxxx',
        last: 'xxxxxxxxx',
    },
    nickname: 'xxxxxxxx',
};

function fetchUserDetails(id) {
    if (!id) {
        return Promise.resolve({ ok: true, body: null });
    }

    return directory.send('GET', `/v11/users/${id}/`, {
        query: {
            fields: 'name,position,avatar_id,nickname',
        },
    });
}

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

        this.state = {
            updateModalOpen: false,
            selectedItem: null,
        };

        this._onResourceStoreChange = this._onResourceStoreChange.bind(this);
        this._onPermissionStoreChange = this._onPermissionStoreChange.bind(this);
        this._onUpdateButtonClick = this._onUpdateButtonClick.bind(this);
        this._onUpdateResponsibleCancel = this._onUpdateResponsibleCancel.bind(this);
        this._onUpdateResponsibleConfirm = this._onUpdateResponsibleConfirm.bind(this);
    }

    componentDidMount() {
        this._storeListener = ServiceResourcesStore.onChange(() => this._onResourceStoreChange());
        this._permissionStoreListener = PermissionStore.onChange(this._onPermissionStoreChange);
        this._update();
    }

    componentWillUnmount() {
        this._unmounted = true;
        this._storeListener.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),
        });
    }

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

        return directory.send('GET', '/v11/permissions/', {
            query: {
                type: serviceSlug,
            },
        });
    }

    _fetchResponsible() {
        const { serviceSlug } = this.props;
        const orgId = getOrganization().id;

        return directory
            .send('GET', `/v11/organizations/${orgId}/`, {
                query: {
                    fields: 'services.responsible',
                },
            })
            .then(({ ok, body }) => {
                if (ok && body) {
                    let { responsible } = body.services.find(({ slug }) => slug === serviceSlug);

                    if (!responsible) {
                        return { ok, body: responsible };
                    }

                    return fetchUserDetails(responsible.id);
                }
            });
    }

    _onResourceStoreChange() {
        let { serviceSlug } = this.props;

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

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

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

        Promise
            .all([
                this._fetchPermissions(),
                this._fetchResponsible(),
            ])
            .then(([permissions, responsible]) => {
                if (permissions.ok) {
                    PermissionStore.set(['local', 'service', serviceSlug], permissions.body);
                }

                if (responsible.ok) {
                    ServiceResourcesStore.set([serviceSlug, 'responsible'], responsible.body);
                }
            })
            .finally(() => {
                if (!this._unmounted) {
                    this.setState({
                        busy: false,
                    });
                }
            });
    }

    _updateResponsible(id) {
        let { serviceSlug } = this.props;

        fetchUserDetails(id).then(({ ok, body }) => {
            if (ok) {
                ServiceResourcesStore.set([serviceSlug, 'responsible'], body);
            }
        });
    }

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

        return this._fetchPermissions()
            .then(({ ok, body }) => {
                if (ok) {
                    PermissionStore.set(['local', 'service', serviceSlug], body);
                }
            });
    }

    _onUpdateButtonClick() {
        this.setState({
            updateModalOpen: true,
        });
    }

    _onUpdateResponsibleCancel() {
        this.setState({
            updateModalOpen: false,
        });
    }

    _onUpdateResponsibleConfirm(id) {
        this.setState({
            updateModalOpen: false,
        });

        this._updateResponsible(id);
        this._updatePermissions();
    }

    render() {
        let { updateModalOpen, responsible, canUpdate } = this.state;
        let { serviceSlug } = this.props;

        return (
            <div className={b()}>
                <div className={b('header')}>
                    <div className={b('title')}>
                        {i18n(`service_page.${serviceSlug}.responsible`) || i18n('service_page.default.responsible')}
                    </div>
                    {canUpdate && (
                        <Button
                            cls={b('button', { type: 'edit' })}
                            theme="clear"
                            size="s"
                            icon={(
                                <Icon
                                    cls={b('edit-icon')}
                                    glyph="yes"
                                >
                                    <PencilIcon />
                                </Icon>
                            )}
                            onClick={this._onUpdateButtonClick}
                        />
                    )}
                </div>
                {responsible !== null && (
                    <div className={b('body')}>
                        <AvatarUnit
                            cls={b('user', { skeleton: !responsible })}
                            object={responsible || PlaceholderResponsible}
                            type="user"
                        />
                    </div>
                )}
                <ServiceResponsibleModal
                    visible={updateModalOpen}
                    value={responsible}
                    serviceSlug={serviceSlug}
                    onCancel={this._onUpdateResponsibleCancel}
                    onConfirm={this._onUpdateResponsibleConfirm}
                />
            </div>
        );
    }
}
