import React from 'react';
import { TextInput, Icon } from 'lego-on-react';
import PromisePool from '@connect/promise-pool';
import block from 'bem-cn';
import SearchIcon from 'components/Icon/Search';
import SpinOverlay from 'components2/SpinOverlay';
import ServiceResource from 'components2/ServiceResource';
import Placeholder from 'components2/Placeholder';
import DomainTitle from 'components2/DomainTitle';
import DomainStatus from 'components2/DomainStatus';
import AddDomainControl from 'components2/AddDomainControl';
import { DomainStore } from 'lib2/stores';
import sortDomainsByRelevance from 'lib2/sortDomainsByRelevance';
import onUrlHash from 'lib2/onUrlHash';
import fetchGendarmeData from 'lib2/fetchGendarmeData';
import openUrl from 'lib2/openUrl';
import directory from 'api2/directory';
import { i18n } from 'i18n2';
import './index.css';

const b = block('domain-list');

function toNameMap(data = [], referenceMap = {}) {
    return data.reduce((map, item) => {
        map[item.name] = Object.assign({}, referenceMap[item.name] || {}, item);

        return map;
    }, {});
}

function getActionText(domain) {
    if (!domain.gendarme) {
        return i18n('domain.action.default');
    }

    return i18n(`domain.action.${domain.owned ? 'dns' : 'verification'}`);
}

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

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

        this._update = this._update.bind(this);
        this._onStoreChange = this._onStoreChange.bind(this);
        this._onFilterChange = this._onFilterChange.bind(this);
        this._onDomainAdded = this._onDomainAdded.bind(this);
    }

    componentDidMount() {
        this._hashListener = onUrlHash('#add-domain', () => this.setState({ addDomainModalOpen: true }));
        this._storeListener = DomainStore.onChange(this._onStoreChange);

        this._update();
    }

    componentWillUnmount() {
        this._unmounted = true;
        this._storeListener.remove();
        this._hashListener.remove();
    }

    _update() {
        return directory
            .send('GET', '/v11/domains/', {
                query: {
                    fields: 'master,tech,owned,name',
                },
            })
            .then(({ ok, body: data }) => {
                if (!ok || !Array.isArray(data)) {
                    return;
                }

                DomainStore.set('list', toNameMap(data, DomainStore.get('list')));

                return new PromisePool(data, fetchGendarmeData)
                    .resolveChunked(3, chunk => DomainStore.merge('list', toNameMap(chunk)));
            });
    }

    _onStoreChange() {
        if (this._unmounted) {
            return;
        }

        const domains = DomainStore.get('list');

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

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

    _onDomainAdded({ name }) {
        openUrl(`/portal/services/webmaster/resources/${encodeURIComponent(name)}`);
    }

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

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

        let hasDomains = items.length !== 0;

        let filteredItems = items
            .filter(domain => domain.name.toLowerCase().includes(text.toLowerCase()));

        return (
            <div className={b()}>
                {hasDomains && (
                    <div className={b('header')}>
                        <div className={b('filter')}>
                            <TextInput
                                cls={b('filter-input')}
                                theme="normal"
                                size="m"
                                type="text"
                                pin="round-round"
                                placeholder={i18n('service_page.webmaster.filter')}
                                iconRight={(
                                    <Icon
                                        cls={b('search-icon')}
                                        glyph="yes"
                                    >
                                        <SearchIcon />
                                    </Icon>
                                )}
                                onChange={this._onFilterChange}
                                text={text}
                                hasClear
                            />
                        </div>
                        <AddDomainControl
                            cls={b('add-button')}
                            defaultModalOpen={addDomainModalOpen}
                            onSubmit={this._onDomainAdded}
                            theme="action"
                            size="m"
                            pseudo
                        />
                    </div>
                )}
                <div className={b('body', { empty: filteredItems.length === 0 })}>
                    {filteredItems.map(domain => (
                        <ServiceResource
                            cls={b('domain')}
                            serviceSlug="webmaster"
                            actionText={getActionText(domain)}
                            url={`/portal/services/webmaster/resources/${encodeURIComponent(domain.name)}`}
                            name={(
                                <DomainTitle
                                    cls={b('domain-title')}
                                    domain={domain}
                                />
                            )}
                            key={domain.name}
                        >
                            <DomainStatus
                                cls={b('domain-status')}
                                domain={domain}
                                badge
                                type="card"
                            />
                        </ServiceResource>
                    ))}
                    <Placeholder
                        cls={b('placeholder')}
                        description={i18n('domain.empty_list')}
                        action={!hasDomains && (
                            <AddDomainControl
                                cls={b('add-button')}
                                defaultModalOpen={addDomainModalOpen}
                                onSubmit={this._onDomainAdded}
                                theme="action"
                                size="m"
                                pseudo
                            />
                        )}
                    />
                </div>
                <SpinOverlay
                    progress={busy}
                    size="m"
                    position="center"
                />
            </div>
        );
    }
}
