import Immutable from 'immutable';
import PropTypes from 'prop-types';
import React from 'react';
import Button from 'react-bem-components/lib/Button';
import FormMixin from 'lib/FormMixin';
import { i18n } from 'lib/i18n';
import Metrika from 'lib/metrika';

import Form from 'ui/Form';
import Cropper from 'ui/Cropper';
import FilePicker from 'ui/FilePicker';

import UserActions from 'actions/User';
import UserStore from 'stores/Users';
import ConfigStore from 'stores/Config';
import User from 'records/User';

import './index.css';
import './change-avatar.css';

const MIN_PIXEL_SIZE = 200;
const MAX_FILE_SIZE = 7; // megabytes
const MB = 1024 * 1024;

function getErrors(error) {
    return Immutable.fromJS(error ? { _common: error } : {});
}

const ChangeAvatar = React.createClass({

    mixins: [FormMixin],

    getInitialState() {
        return { errors: getErrors() };
    },

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

    _handleFormSubmit() {
        const data = {
            avatar_file: this.refs.cropper.getSelectedImage(),
        };

        Metrika.send('Карточка пользователя', 'Смена аватара', 'Сохранить');

        return this._submit(UserActions.setAvatar(data, this.props.id), {
            success: i18n('user.status.avatar_changed'),
            failure: i18n('user.status.failed_to_change_avatar'),
        });
    },

    _handleImageRead(event) {
        const { result } = event.target;
        const image = new Image();

        image.onload = () => {
            if (image.width < MIN_PIXEL_SIZE || image.height < MIN_PIXEL_SIZE) {
                const errors = getErrors(i18n('avatar.error.image_too_small', {
                    min_pixel_size: MIN_PIXEL_SIZE,
                }));

                this.setState({ errors });
            } else {
                this.refs.cropper.setImage(result);
            }
        };
        image.src = result;
    },

    _handleImagePick(files) {
        let errors = getErrors();

        if (files) {
            const selectedFile = files[0];

            if (selectedFile && selectedFile.size > MAX_FILE_SIZE * MB) {
                errors = getErrors(i18n('avatar.error.file_too_large'));
            }
        }

        this.setState({ errors });

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

    render() {
        const errors = this.state.errors.toJS();
        const user = UserStore.get(this.props.id);

        return (
            <Form
                className="change-user-avatar-form form"
                onSubmit={this._handleFormSubmit}
                autoComplete={false}
            >

                <div className="image-editor">
                    <div className="image-editor__title">
                        {i18n('avatar.crop_image')}
                    </div>
                    <Cropper
                        ref="cropper"
                        minSize={ConfigStore.get('ui.avatar.minOriginalSize')}
                        src={user ? user.getAvatar() : null}
                        defaultSrc={User.getDefaultAvatar()}
                        imageDescription={i18n('user.avatar_description', {
                            name: user.getName(),
                        })}
                    />
                </div>

                <div className="image-picker">
                    <div className="image-picker__title">
                        {i18n('avatar.upload_image')}
                    </div>
                    <div className="image-picker__file-button">
                        <FilePicker
                            text={i18n('avatar.action.upload')}
                            accept="image/*"
                            onPick={this._handleImagePick}
                            onRead={this._handleImageRead}
                        />
                    </div>
                    <div className="image-picker__description">
                        {i18n('avatar.file_description', {
                            min_pixel_size: MIN_PIXEL_SIZE,
                            max_file_size: MAX_FILE_SIZE,
                        })}
                    </div>
                </div>

                <div className="image-editor__separator" />
                <Form.Error value={errors._common} mod="standalone" />

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

ChangeAvatar.propTypes = {
    id: PropTypes.string,
    onSubmit: PropTypes.func,
    onCancel: PropTypes.func,
};

export default ChangeAvatar;
