import _ from 'lodash';
import PropTypes from 'prop-types';
import React from 'react';
import Select from 'react-bem-components/lib/Select';
import FormMixin from 'lib/FormMixin';
import { i18n } from 'lib/i18n';
import Metrika from 'lib/metrika';

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

import DnsActions from 'actions/Dns';
import dnsValidator from 'validation/dns';
import DNS_FIELDS from './fields';

const TYPES = [
    'A',
    'CNAME',
    'AAAA',
    'TXT',
    'NS',
    'MX',
    'SRV',
];

const TYPE_OPTIONS = TYPES.map(
    val => ({ val, text: val })
);

const Create = React.createClass({

    mixins: [FormMixin],

    getInitialState() {
        return {
            recordType: TYPES[0],
            errors: dnsValidator.getErrors(),
        };
    },

    componentWillReceiveProps() {
        this.setState(this.getInitialState());
    },

    _validator: dnsValidator,

    _getFieldsByType(type) {
        return DNS_FIELDS.filter(item => item.available === undefined || item.available(type));
    },

    _renderDnsItem(type) {
        const errors = this.state.errors.toJS();
        const visibleFields = this._getFieldsByType(type);

        return visibleFields.map(dnsField => {
            const fieldErrors = errors[dnsField.name] || this._getDnsFieldError(errors, dnsField);

            return (
                <Form.Item
                    label={dnsField.text}
                    key={dnsField.name}
                    required={dnsField.isRequired(type)}
                    errors={fieldErrors}
                >
                    <Input
                        name={dnsField.name}
                        hasClear
                        size="l"
                        autoComplete={false}
                        width="available"
                    />
                </Form.Item>
            );
        });
    },

    _fixSrvData(data) {
        const type = data.type || '';

        if (type.toLowerCase() !== 'srv') {
            return data;
        }

        data.target = data.content;

        return data;
    },

    _handleSubmit(data) {
        const { domain, onSubmit } = this.props;
        const { recordType: type } = this.state;

        data = this._fixSrvData(data);

        if (this._validate(data)) {
            Metrika.send('DNS', 'Форма добавления', 'Создать');

            this._submit(DnsActions.submitRecord(domain, data), {
                success: i18n('dns_record.status.created', { type }),
                failure: i18n('dns_record.status.failed_to_create', { type }),
            })
                .then(() => {
                    if (onSubmit) {
                        onSubmit();
                    }
                });
        }
    },

    _getGeneralDnsError(errors) {
        if (_.isEmpty(errors)) {
            return null;
        }

        return _.chain(errors)
            .pick(['unknown', 'record_exists', 'cname_on_root'])
            .values()
            .value();
    },

    _getDnsFieldError(errors, dnsField) {
        const fieldErrors = dnsField.errors.map(errorName => {
            if (errors.hasOwnProperty(errorName)) {
                return errors[errorName];
            }
        }).filter(Boolean);

        if (fieldErrors.length === 0) {
            return null;
        }

        return fieldErrors[0];
    },

    _handleTypeChange(payload) {
        this.setState({
            recordType: payload.value,
            errors: dnsValidator.getErrors(),
        });
    },

    render() {
        const { domain, onCancel } = this.props;
        const { recordType } = this.state;

        const errors = this.state.errors.toJS();
        const title = i18n('dns_settings.new_record', { domain });

        return (
            <Form
                className="dns-form form"
                onSubmit={this._handleSubmit}
                autoComplete={false}
            >

                <Form.Title>{title}</Form.Title>
                <input type="hidden" name="domain" value={domain} />
                <Form.Item
                    label={i18n('dns_record.type')}
                    required
                    errors={errors.recordType}
                >
                    <Select
                        name="type"
                        mode="radio"
                        options={TYPE_OPTIONS}
                        width="available"
                        size="l"
                        onChange={this._handleTypeChange}
                    />
                </Form.Item>
                {this._renderDnsItem(recordType)}
                <Form.Error value={this._getGeneralDnsError(errors)} mod="standalone" />

                <Form.Buttons mod="aligned">
                    <Button text={i18n('common.action.create')} view="action" type="submit" />
                    <Button text={i18n('common.action.cancel')} onClick={onCancel} />
                </Form.Buttons>
            </Form>
        );
    },
});

Create.propTypes = {
    onSubmit: PropTypes.func,
    onCancel: PropTypes.func,
};

export default Create;
