/**
 * Валидация данных пользователя, полученных из форм
 */

import _ from 'lodash';
import validator from 'validator';
import { i18n } from 'lib/i18n';
import Url from 'lib/Url';
import getErrorMap from './getErrorMap';

const CREDENTIALS_PREVALIDATION_ENABLED = false;
const ACCOUNT_NAME_PATTERN = /^([a-z0-9_\-][a-z0-9\._\-]{0,28}[a-z0-9\-]|[a-z0-9_\-])$/;
const PASSWORD_PATTERN = /^[-a-zA-Z0-9`!@#$%\^&*\(\)_=\+\[\]\{\};:"\\|,\.<>\/\?]{6,255}$/;
const DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;

function xi18n(key, options) {
    return i18n(`user_validation.${key}`, options);
}

function isDate(x) {
    return !isNaN((new Date(x)).getTime());
}

const userValidator = {

    getFirstNameError(data, locale = 'ru') {
        const minLength = 2;
        const maxLength = 40;

        const firstName = _.get(data, `name.first.${locale}`);

        if (firstName === undefined) {
            return;
        }

        if (!firstName) {
            return xi18n('first_name_undefined');
        } else if (firstName.length < minLength) {
            return xi18n('first_name_too_short', { minLength });
        } else if (firstName.length > maxLength) {
            return xi18n('first_name_too_long', { maxLength });
        }
    },

    getMiddleNameError(data, locale = 'ru') {
        const minLength = 2;
        const maxLength = 40;

        const middleName = _.get(data, `name.middle.${locale}`);

        if (middleName === undefined) {
            return;
        }

        if (middleName) {
            if (middleName.length < minLength) {
                return xi18n('middle_name_too_short', { minLength });
            } else if (middleName.length > maxLength) {
                return xi18n('middle_name_too_long', { maxLength });
            }
        }
    },

    getLastNameError(data, locale = 'ru') {
        const minLength = 2;
        const maxLength = 40;

        const lastName = _.get(data, `name.last.${locale}`);

        if (lastName === undefined) {
            return;
        }

        if (!lastName) {
            return xi18n('last_name_undefined');
        } else if (lastName.length < minLength) {
            return xi18n('last_name_too_short', { minLength });
        } else if (lastName.length > maxLength) {
            return xi18n('last_name_too_long', { maxLength });
        }
    },

    getPositionError(data, locale = 'ru') {
        const minLength = 2;
        const maxLength = 100;

        const position = _.get(data, `position.${locale}`);

        if (position === undefined) {
            return;
        }

        if (position) {
            if (position.length < minLength) {
                return xi18n('position_too_short', { minLength });
            } else if (position.length > maxLength) {
                return xi18n('position_too_long', { maxLength });
            }
        }
    },

    getNicknameError(data) {
        const minLength = 3;
        const maxLength = 30;

        const accountName = data.nickname;

        if (accountName === undefined) {
            return;
        }

        const messages = [];

        if (!accountName) {
            messages.push(xi18n('login_undefined'));
        } else if (CREDENTIALS_PREVALIDATION_ENABLED) {
            if (accountName.length < minLength) {
                messages.push(xi18n('login_too_short', { minLength }));
            } else if (accountName.length > maxLength) {
                messages.push(xi18n('login_too_long', { maxLength }));
            }

            if (!ACCOUNT_NAME_PATTERN.test(accountName)) {
                messages.push(xi18n('invalid_login'));
            }
        }

        if (messages.length) {
            return messages.join(' ');
        }
    },

    getPasswordError(data) {
        const minLength = 6;
        const maxLength = 256;

        const password = data.password;

        if (password === undefined) {
            return;
        }

        const messages = [];

        if (!password) {
            messages.push(xi18n('password_undefined'));
        } else if (CREDENTIALS_PREVALIDATION_ENABLED) {
            if (password.length < minLength) {
                messages.push(xi18n('password_too_short', { minLength }));
            } else if (password.length > maxLength) {
                messages.push(xi18n('password_too_long', { maxLength }));
            }

            if (!PASSWORD_PATTERN.test(password)) {
                messages.push(xi18n('invalid_password'));
            }
        }

        if (messages.length) {
            return messages.join(' ');
        }
    },

    getPasswordConfirmationError(data) {
        const passwordConfirmation = data.password_confirmation;

        if (passwordConfirmation === undefined) {
            return;
        }

        if (!passwordConfirmation) {
            return xi18n('password_confirmation_undefined');
        } else if (data.password !== passwordConfirmation) {
            return xi18n('password_confirmation_failed');
        }
    },

    getContactsError(data) {
        if (!data.contacts || !data.contacts.length) {
            return;
        }

        const errors = data.contacts.map(contact => {
            if (contact.value === undefined) {
                return;
            }

            switch (contact.type) {
                case 'email':
                    if (!validator.isEmail(contact.value) || !Url.isSafe(contact.value)) {
                        return xi18n('invalid_email');
                    }
                    break;
                case 'site':
                    if (!Url.isSafe(contact.value)) {
                        return xi18n('invalid_site');
                    }
                    break;
                case 'phone':
                // @TODO решить нужна ли валидация телефонов и прочего
                // if (!validator.isMobilePhone(contact.value, 'ru-RU')) {
                //     return xi18n('invalid_phone_number');
                // }
                    break;
            }
        });

        if (_.some(errors, Boolean)) {
            return errors;
        }
    },

    getBirthdayError(data) {
        const date = data.birthday;

        if (date === undefined || !date) {
            return;
        }

        if (date && (typeof date === 'string')) {
            const neutralLocaleDate = date.replace(/\-/g, '/');

            if (!DATE_PATTERN.test(date) || !isDate(neutralLocaleDate)) {
                return xi18n('invalid_birth_date');
            }
        }
    },

};

userValidator.getErrors = getErrorMap(userValidator);

export default userValidator;
