import React from 'react';
import { TextInput, Icon } from 'lego-on-react';
import { block } from 'bem-cn';
import { i18n } from 'i18n2';
import { ServiceResourcesStore } from 'lib2/stores';
import directory from 'api2/directory';

import { Search as SearchIcon } from 'components/Icon';
import SpinOverlay from 'components2/SpinOverlay';
import ServiceResource from 'components2/ServiceResource';
import Placeholder from 'components2/Placeholder';

import './index.css';

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

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

        this.state = {
            busy: false,
            text: '',
        };

        this._onStoreChange = this._onStoreChange.bind(this);
        this._onFilterChange = this._onFilterChange.bind(this);
        this._renderListItem = this._renderListItem.bind(this);
    }

    componentDidMount() {
        this._storeListener = ServiceResourcesStore.onChange(this._onStoreChange);

        this._update();
    }

    componentWillUnmount() {
        this._storeListener.remove();
    }

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

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

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

    _onStoreChange() {
        let { serviceSlug } = this.props;
        const resources = ServiceResourcesStore.get([serviceSlug, 'list']);

        this.setState({
            items: resources ? Object.values(resources) : undefined,
        });
    }

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

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

        ServiceResourcesStore.remove([serviceSlug, 'list']);

        directory
            .send('GET', '/v11/resources/', {
                query: {
                    per_page: 1000,
                    service: serviceSlug,
                },
            })
            .then(({ ok, body }) => {
                if (ok) {
                    const data = body.result.reduce((acc, item) => {
                        acc[item.id] = item;

                        return acc;
                    }, {});

                    ServiceResourcesStore.set([serviceSlug, 'list'], data);
                }
            })
            .finally(() => {
                this.setState({
                    busy: false,
                });
            });
    }

    _onFilterChange(text) {
        this.setState({
            text,
        });
    }

    _renderListItem(item) {
        const { serviceSlug } = this.props;
        const { id } = item;

        return (
            <ServiceResource
                key={`resource-${id}`}
                id={`#${id}`}
                url={`/portal/services/${serviceSlug}/resources/${id}`}
                name={item.metadata.name}
                description={item.metadata.description}
                serviceSlug={serviceSlug}
            />
        );
    }

    _renderHeader() {
        const { serviceSlug } = this.props;
        const { text } = this.state;

        return (
            <div className={b('filter')}>
                <TextInput
                    theme="normal"
                    size="m"
                    type="text"
                    pin="round-round"
                    placeholder={i18n(`service_page.${serviceSlug}.filter`) ||
                        i18n('service_page.default.filter')}
                    has-icon="true"
                    iconRight={(
                        <Icon
                            cls={b('search-icon')}
                            glyph="yes"
                        >
                            <SearchIcon />
                        </Icon>
                    )}
                    onChange={this._onFilterChange}
                    text={text}
                />
            </div>
        );
    }

    render() {
        const { busy, items, text } = this.state;

        if (items === undefined && busy) {
            return (
                <SpinOverlay
                    progress
                    size="m"
                    position="center"
                />
            );
        }

        if (!busy && (!items || items.length === 0)) {
            return (
                <div className={b({ empty: true })}>
                    <Placeholder
                        cls={b('empty')}
                        title={this._getText('empty.title')}
                        description={this._getText('empty.description')}
                    />
                </div>
            );
        }

        let filteredItems = items.filter(({ id, metadata: { name, description } }) =>
            id.indexOf(text.toLowerCase()) > -1 ||
            name && name.toLowerCase().indexOf(text.toLowerCase()) > -1 ||
            description && description.toLowerCase().indexOf(text.toLowerCase()) > -1
        );

        if (!busy && (!filteredItems || filteredItems.length === 0)) {
            return (
                <div className={b({ empty: true })}>
                    {this._renderHeader()}
                    <Placeholder
                        cls={b('empty')}
                        description={this._getText('empty.search_title')}
                    />
                </div>
            );
        }

        return (
            <div className={b()}>
                {this._renderHeader()}
                <div className={b('list')}>
                    {filteredItems.map(this._renderListItem)}
                </div>
                <SpinOverlay
                    progress={busy}
                    size="m"
                    position="center"
                />
            </div>
        );
    }
}
