import _ from 'lodash';
import PropTypes from 'prop-types';
import React from 'react';
import { Promise } from 'rsvp';
import FormMixin from 'lib/FormMixin';
import AuthStore from 'stores/Auth';
import ConfigStore from 'stores/Config';
import OrgSetupActions from 'actions/OrgSetup';

import Form from 'lego-ui/Form';
import Input from 'lego-ui/Input';
import Select from 'lego-ui/Select';
import Button from 'lego-ui/Button';

import orgSetupValidator from 'validation/orgSetup';
import Url from 'lib/Url';
import { i18n } from 'lib/i18n';
import filterInput from './filterInput';

import './index.css';

function getEmail(domain) {
    const session = AuthStore.getSession();
    const name = String(session.get('login')).split('@')[0];

    if (!domain) {
        return i18n('organization_setup.domain.email_pattern', {
            name, tld: ConfigStore.get('app.tld'),
        });
    }

    return `${name}@${domain}`;
}

function getError(errors, key) {
    if (errors && errors[key]) {
        const messages = errors[key] instanceof Array ? errors[key] : [errors[key]];

        return messages.map(line => `<p class="error">${line}</p>`).join(' ');
    }
}

function getInitialOrganizationName() {
    const org = AuthStore.getOrganization();

    if (!org) {
        return '';
    }

    const name = org.getName();

    if (name) {
        return name;
    }

    return (org.getLabel() || '').split(/[\.\-_]/).map(_.capitalize).join(' ');
}

function optionListComparator(a, b) {
    if (a.text === b.text) {
        return 0;
    }

    return a.text < b.text ? -1 : 1;
}

const DEFAULT_COUNTRY_MAP = {
    ru: 'ru',
    en: 'us',
};

const LANGUAGES = ['ru', 'en']
    .map(item => ({ text: i18n(`common_vocab.lang.${item}`), val: item }))
    .sort(optionListComparator);

const COUNTRIES = Object.keys(i18n('countries') || {})
    .map(item => ({ text: i18n(`countries.${item}`), val: item.toLowerCase() }))
    .sort(optionListComparator);

const Details = React.createClass({

    mixins: [FormMixin],

    getInitialState() {
        const session = AuthStore.getSession();
        const locale = session.get('locale');

        return {
            name: getInitialOrganizationName(),
            language: locale,
            country: session.get('country') || DEFAULT_COUNTRY_MAP[locale],
            errors: orgSetupValidator.getErrors(),
        };
    },

    componentDidMount() {
        let { skipped } = this.state;
        const { onSkip } = this.props;

        const org = AuthStore.getOrganization();

        // берём исходные значения полей из данных об организации
        skipped = Boolean(org && org.getName() && org.getLanguage()) && skipped === undefined;

        if (Url.getQueryParam('skip') === '0') {
            skipped = false;
        }

        this.setState({ skipped });

        if (skipped && onSkip) {
            onSkip();
        }
    },

    _handleFormSubmit(data) {
        const { onSubmit, onReady } = this.props;
        const initialAction = (onSubmit ? onSubmit() : null) || Promise.resolve();

        if (this._use(orgSetupValidator, filterInput)._validate(data)) {
            return initialAction
                .then(() => OrgSetupActions.submitDetails(data))
                .then(response => {
                    const errors = response ? response.errors : null;

                    if (errors && !errors.isEmpty()) {
                        this.setState({ errors });

                        return;
                    }

                    if (onReady) {
                        onReady();
                    }
                });
        }
    },

    _onChange(key, event) {
        const { target } = event;
        const { errors } = this.state;
        const nextState = {};

        if (!target) {
            return;
        }

        if (target.domElem) {
            const actualTarget = target.domElem[0].querySelector(`input[name="${key}"]`);

            nextState[key] = actualTarget ? actualTarget.value : null;
        } else {
            nextState[key] = target.value;
        }

        if (errors && errors.get(key)) {
            nextState.errors = errors.remove(key);
        }

        this.setState(nextState);
    },

    _storeValue(field) {
        this.setState({
            [`stored_${field}`]: this.state[field],
        });
    },

    _checkChange(field) {
        if (this.props.onChange && this.state[field] !== this.state[`stored_${field}`]) {
            this.props.onChange(field, this.state[field]);
        }
    },

    _isComplete() {
        const errors = orgSetupValidator.getErrors(this.state);

        return !errors || errors.isEmpty();
    },

    render() {
        let { errors } = this.state;
        const { name, language, country, domain, skipped } = this.state;

        if (skipped) {
            return null;
        }

        if (errors) {
            errors = errors.toJS();
        }

        const domainTip = i18n('organization_setup.domain.tip', {
            email: getEmail(domain),
        });

        return (
            <Form
                className="org-setup-form"
                onSubmit={this._handleFormSubmit}
            >

                <Form.Item className="account-status">
                    {i18n('organization_setup.account_created')}
                </Form.Item>

                <Form.Item className="form-title">
                    <span
                        dangerouslySetInnerHTML={{
                            __html: i18n('organization_setup.add_org_details'),
                        }}
                    />
                </Form.Item>

                <Form.Item>
                    <Input
                        name="name"
                        defaultValue={name}
                        placeholderLabel={i18n('organization_setup.details.organization_name')}
                        error={getError(errors, 'name')}
                        onChange={this._onChange.bind(this, 'name')}
                        onFocus={() => this._storeValue('name')}
                        onBlur={() => this._checkChange('name')}
                        border="bottom"
                        width="available"
                    />
                </Form.Item>

                <Form.Item errors={errors.country}>
                    <Select
                        name="country"
                        options={COUNTRIES}
                        val={country}
                        placeholderLabel={i18n('organization_setup.details.country')}
                        onChange={this._onChange.bind(this, 'country')}
                        border="bottom"
                        width="available"
                    />
                </Form.Item>

                <Form.Item errors={errors.language}>
                    <Select
                        name="language"
                        options={LANGUAGES}
                        val={language}
                        placeholderLabel={i18n('organization_setup.details.language')}
                        onChange={this._onChange.bind(this, 'language')}
                        border="bottom"
                        width="available"
                    />
                </Form.Item>

                <Form.Item>
                    <Input
                        name="domain"
                        placeholderLabel={i18n('organization_setup.domain.placeholder')}
                        error={getError(errors, 'domain')}
                        tip={domainTip}
                        onChange={this._onChange.bind(this, 'domain')}
                        onFocus={() => this._storeValue('domain')}
                        onBlur={() => this._checkChange('domain')}
                        border="bottom"
                        width="available"
                    />
                </Form.Item>

                <Form.Item className="personal-email-description">
                    <div className="form-subtitle">
                        {i18n('organization_setup.personal_email.title')}
                    </div>
                    <div className="form-content">
                        {i18n('organization_setup.personal_email.description')}
                    </div>
                </Form.Item>

                <Form.Item>
                    <Input
                        name="email"
                        placeholderLabel={i18n('organization_setup.personal_email.placeholder')}
                        error={getError(errors, 'email')}
                        onChange={this._onChange.bind(this, 'email')}
                        onFocus={() => this._storeValue('email')}
                        onBlur={() => this._checkChange('email')}
                        border="bottom"
                        width="available"
                    />
                </Form.Item>

                <Form.Item className="form-error">
                    {errors._common}
                </Form.Item>

                <Form.Item className="form-buttons">
                    <Button
                        text={i18n('organization_setup.action.done')}
                        type="submit"
                        disabled={!this._isComplete()}
                        view="action"
                        width="available"
                    />
                </Form.Item>

            </Form>
        );
    },

});

Details.propTypes = {
    onSubmit: PropTypes.func,
    onReady: PropTypes.func,
    onSkip: PropTypes.func,
};

export default Details;
