import React from 'react';
import { connect } from 'react-redux';
import Slider from 'react-rangeslider';
import tt from 'counterpart';
import reactForm from 'app/utils/ReactForm';
import * as globalActions from 'app/redux/GlobalReducer';
import * as transactionActions from 'app/redux/TransactionReducer';
import * as userActions from 'app/redux/UserReducer';
import { VEST_TICKER, LIQUID_TICKER, VESTING_TOKEN } from 'app/client_config';
import {
    numberWithCommas,
    spToVestsf,
    vestsToSpf,
    vestsToSp,
    assetFloat,
} from 'app/utils/StateFunctions';

class Powerdown extends React.Component {
    constructor(props, context) {
        super(props, context);
        let new_withdraw;
        if (props.to_withdraw - props.withdrawn > 0) {
            new_withdraw = props.to_withdraw - props.withdrawn;
        } else {
            // Set the default withrawal amount to (available - 5 STEEM)
            // This should be removed post hf20
            new_withdraw = Math.max(
                0,
                props.available_shares - spToVestsf(props.state, 5.001)
            );
        }
        this.state = {
            broadcasting: false,
            manual_entry: false,
            new_withdraw,
        };
    }

    render() {
        const { broadcasting, new_withdraw, manual_entry } = this.state;
        const {
            account,
            available_shares,
            withdrawn,
            to_withdraw,
            vesting_shares,
            delegated_vesting_shares,
        } = this.props;
        const formatSp = amount =>
            numberWithCommas(vestsToSp(this.props.state, amount));
        const sliderChange = value => {
            this.setState({ new_withdraw: value, manual_entry: false });
        };
        const inputChange = event => {
            event.preventDefault();
            let value = spToVestsf(
                this.props.state,
                parseFloat(event.target.value.replace(/,/g, ''))
            );
            if (!isFinite(value)) {
                value = new_withdraw;
            }
            this.setState({
                new_withdraw: value,
                manual_entry: event.target.value,
            });
        };
        const powerDown = event => {
            event.preventDefault();
            this.setState({ broadcasting: true, error_message: undefined });
            const successCallback = this.props.successCallback;
            const errorCallback = error => {
                this.setState({
                    broadcasting: false,
                    error_message: String(error),
                });
            };
            // workaround bad math in react-rangeslider
            let withdraw = new_withdraw;
            if (withdraw > vesting_shares - delegated_vesting_shares) {
                withdraw = vesting_shares - delegated_vesting_shares;
            }
            const vesting_shares = `${withdraw.toFixed(6)} ${VEST_TICKER}`;
            this.props.withdrawVesting({
                account,
                vesting_shares,
                errorCallback,
                successCallback,
            });
        };

        const notes = [];
        if (to_withdraw - withdrawn > 0) {
            const AMOUNT = formatSp(to_withdraw);
            const WITHDRAWN = formatSp(withdrawn);
            notes.push(
                <li key="already_power_down">
                    {tt('powerdown_jsx.already_power_down', {
                        AMOUNT,
                        WITHDRAWN,
                        LIQUID_TICKER,
                    })}
                </li>
            );
        }
        if (delegated_vesting_shares !== 0) {
            const AMOUNT = formatSp(delegated_vesting_shares);
            notes.push(
                <li key="delegating">
                    {tt('powerdown_jsx.delegating', { AMOUNT, LIQUID_TICKER })}
                </li>
            );
        }
        if (notes.length === 0) {
            let AMOUNT = vestsToSpf(this.props.state, new_withdraw) / 13;
            AMOUNT = AMOUNT.toFixed(AMOUNT >= 10 ? 0 : 1);
            notes.push(
                <li key="per_week">
                    {tt('powerdown_jsx.per_week', { AMOUNT, LIQUID_TICKER })}
                </li>
            );
        }
        // NOTE: remove this post hf20
        if (
            new_withdraw >
            vesting_shares -
                delegated_vesting_shares -
                spToVestsf(this.props.state, 5)
        ) {
            const AMOUNT = 5;
            notes.push(
                <li key="warning" className="warning">
                    {tt('powerdown_jsx.warning', { AMOUNT, VESTING_TOKEN })}
                </li>
            );
        }

        if (this.state.error_message) {
            const MESSAGE = this.state.error_message;
            notes.push(
                <li key="error" className="error">
                    {tt('powerdown_jsx.error', { MESSAGE })}
                </li>
            );
        }

        return (
            <div className="PowerdownModal">
                <div className="row">
                    <h3 className="column">
                        {tt('powerdown_jsx.power_down')} {broadcasting}
                    </h3>
                </div>
                <Slider
                    value={new_withdraw}
                    step={0.000001}
                    max={vesting_shares - delegated_vesting_shares}
                    format={formatSp}
                    onChange={sliderChange}
                />
                <p className="powerdown-amount">
                    {tt('powerdown_jsx.amount')}
                    <br />
                    <input
                        value={
                            manual_entry ? manual_entry : formatSp(new_withdraw)
                        }
                        onChange={inputChange}
                        autoCorrect={false}
                    />
                    {LIQUID_TICKER}
                </p>
                <ul className="powerdown-notes">{notes}</ul>
                <button
                    type="submit"
                    className="button"
                    onClick={powerDown}
                    disabled={broadcasting}
                >
                    {tt('powerdown_jsx.power_down')}
                </button>
            </div>
        );
    }
}

export default connect(
    // mapStateToProps
    (state, ownProps) => {
        const values = state.user.get('powerdown_defaults');
        const account = values.get('account');
        const to_withdraw = parseFloat(values.get('to_withdraw')) / 1e6;
        const withdrawn = parseFloat(values.get('withdrawn')) / 1e6;
        const vesting_shares = assetFloat(
            values.get('vesting_shares'),
            VEST_TICKER
        );
        const delegated_vesting_shares = assetFloat(
            values.get('delegated_vesting_shares'),
            VEST_TICKER
        );
        const available_shares =
            vesting_shares - to_withdraw - withdrawn - delegated_vesting_shares;

        return {
            ...ownProps,
            account,
            available_shares,
            delegated_vesting_shares,
            state,
            to_withdraw,
            vesting_shares,
            withdrawn,
        };
    },
    // mapDispatchToProps
    dispatch => ({
        successCallback: () => {
            dispatch(userActions.hidePowerdown());
        },
        powerDown: e => {
            e.preventDefault();
            const name = 'powerDown';
            dispatch(globalActions.showDialog({ name }));
        },
        withdrawVesting: ({
            account,
            vesting_shares,
            errorCallback,
            successCallback,
        }) => {
            const successCallbackWrapper = (...args) => {
                dispatch(
                    globalActions.getState({ url: `@${account}/transfers` })
                );
                return successCallback(...args);
            };
            dispatch(
                transactionActions.broadcastOperation({
                    type: 'withdraw_vesting',
                    operation: { account, vesting_shares },
                    errorCallback,
                    successCallback: successCallbackWrapper,
                })
            );
        },
    })
)(Powerdown);
