import { fromJS } from 'immutable';
import { DEFAULT_LANGUAGE } from 'app/client_config';

// Action constants
const SHOW_LOGIN = 'user/SHOW_LOGIN';
const HIDE_LOGIN = 'user/HIDE_LOGIN';
const SHOW_TERMS = 'user/SHOW_TERMS';
export const ACCEPT_TERMS = 'user/ACCEPT_TERMS';
export const SAVE_LOGIN_CONFIRM = 'user/SAVE_LOGIN_CONFIRM';
export const SAVE_LOGIN = 'user/SAVE_LOGIN';
const REMOVE_HIGH_SECURITY_KEYS = 'user/REMOVE_HIGH_SECURITY_KEYS';
const CHANGE_LANGUAGE = 'user/CHANGE_LANGUAGE';
const SHOW_TRANSFER = 'user/SHOW_TRANSFER';
const SHOW_DECODE_MEMO = 'user/SHOW_DECODE_MEMO';
const HIDE_TRANSFER = 'user/HIDE_TRANSFER';
const HIDE_DECODE_MEMO = 'user/HIDE_DECODE_MEMO';
const SET_MEMO_MESSAGE = 'user/SET_MEMO_MESSAGE';
const SHOW_POWERDOWN = 'user/SHOW_POWERDOWN';
const HIDE_POWERDOWN = 'user/HIDE_POWERDOWN';
const SET_TRANSFER_DEFAULTS = 'user/SET_TRANSFER_DEFAULTS';
const CLEAR_TRANSFER_DEFAULTS = 'user/CLEAR_TRANSFER_DEFAULTS';
const SET_POWERDOWN_DEFAULTS = 'user/SET_POWERDOWN_DEFAULTS';
const CLEAR_POWERDOWN_DEFAULTS = 'user/CLEAR_POWERDOWN_DEFAULTS';
export const USERNAME_PASSWORD_LOGIN = 'user/USERNAME_PASSWORD_LOGIN';
export const SET_USERNAME = 'user/SET_USERNAME';
export const SET_USER = 'user/SET_USER';
const CLOSE_LOGIN = 'user/CLOSE_LOGIN';
export const LOGIN_ERROR = 'user/LOGIN_ERROR';
export const LOGOUT = 'user/LOGOUT';
const SET_LATEST_FEED_PRICE = 'user/SET_LATEST_FEED_PRICE';
const SHOW_SIGN_UP = 'user/SHOW_SIGN_UP';
const HIDE_SIGN_UP = 'user/HIDE_SIGN_UP';
const KEYS_ERROR = 'user/KEYS_ERROR';
const ACCOUNT_AUTH_LOOKUP = 'user/ACCOUNT_AUTH_LOOKUP';
const SET_AUTHORITY = 'user/SET_AUTHORITY';
const HIDE_CONNECTION_ERROR_MODAL = 'user/HIDE_CONNECTION_ERROR_MODAL';
const SET = 'user/SET';
const SHOW_SIDE_PANEL = 'user/SHOW_SIDE_PANEL';
const HIDE_SIDE_PANEL = 'user/HIDE_SIDE_PANEL';

// Saga-related
export const LOAD_SAVINGS_WITHDRAW = 'user/LOAD_SAVINGS_WITHDRAW';
export const UPLOAD_IMAGE = 'user/UPLOAD_IMAGE';
export const GET_VESTING_DELEGATIONS = 'user/GET_VESTING_DELEGATIONS';
export const VESTING_DELEGATIONS_LOADING = 'user/VESTING_DELEGATIONS_LOADING';
export const SET_VESTING_DELEGATIONS = 'user/SET_VESTING_DELEGATIONS';
const defaultState = fromJS({
    current: null,
    show_login_modal: false,
    show_transfer_modal: false,
    show_decode_memo_modal: false,
    show_signup_modal: false,
    show_post_advanced_settings_modal: '', // formId
    pub_keys_used: null,
    locale: DEFAULT_LANGUAGE,
    show_side_panel: false,
    maybeLoggedIn: false,
    vestingDelegations: null,
});

export default function reducer(state = defaultState, action) {
    const { payload } = action;

    switch (action.type) {
        case SHOW_LOGIN: {
            let operation, loginDefault;
            if (payload) {
                operation = fromJS(payload.operation);
                loginDefault = fromJS(payload.loginDefault);
            }
            return state.merge({
                show_login_modal: true,
                login_type: payload.type,
                loginBroadcastOperation: operation,
                loginDefault,
            });
        }

        case SET_LATEST_FEED_PRICE:
            return state.set('latest_feed_price', payload);

        case HIDE_LOGIN:
            return state.merge({
                show_login_modal: false,
                loginBroadcastOperation: undefined,
                loginDefault: undefined,
            });

        case SHOW_TERMS: {
            let termsDefault;
            if (payload) {
                termsDefault = fromJS(payload.termsDefault);
            }
            return state.merge({
                show_terms_modal: true,
                termsDefault,
            });
        }

        case ACCEPT_TERMS:
            return state.merge({
                show_terms_modal: false,
                termsDefault: undefined,
            });

        case SAVE_LOGIN_CONFIRM:
            return state.set('saveLoginConfirm', payload);

        case SAVE_LOGIN:
            // Use only for low security keys (like posting only keys)
            return state;

        case SET_VESTING_DELEGATIONS:
            return state.set('vestingDelegations', payload);

        case VESTING_DELEGATIONS_LOADING:
            return state.set('vestingDelegationsLoading', payload);

        case REMOVE_HIGH_SECURITY_KEYS: {
            if (!state.hasIn(['current', 'private_keys'])) return state;
            let empty = false;
            state = state.updateIn(
                ['current', 'private_keys'],
                (private_keys) => {
                    if (!private_keys) return null;
                    if (
                        private_keys.has('active_private') ||
                        private_keys.has('owner_private')
                    )
                        console.log('removeHighSecurityKeys');
                    private_keys = private_keys.delete('active_private');
                    private_keys = private_keys.delete('owner_private');
                    empty = private_keys.size === 0;
                    return private_keys;
                }
            );
            if (empty) {
                // LOGOUT
                return defaultState.merge({ logged_out: true });
            }
            const username = state.getIn(['current', 'username']);
            state = state.setIn(['authority', username, 'active'], 'none');
            state = state.setIn(['authority', username, 'owner'], 'none');
            return state;
        }

        case CHANGE_LANGUAGE:
            return state.set('locale', payload);

        case SHOW_TRANSFER:
            return state.set('show_transfer_modal', true);

        case SHOW_DECODE_MEMO:
            return state.set('show_decode_memo_modal', true);

        case SET_MEMO_MESSAGE:
            return state.set('memo_message', payload);

        case HIDE_TRANSFER:
            return state.set('show_transfer_modal', false);

        case HIDE_DECODE_MEMO:
            return state.set('show_decode_memo_modal', false);

        case SHOW_POWERDOWN:
            return state.set('show_powerdown_modal', true);

        case HIDE_POWERDOWN:
            return state.set('show_powerdown_modal', false);

        case SET_TRANSFER_DEFAULTS:
            return state.set('transfer_defaults', fromJS(payload));

        case CLEAR_TRANSFER_DEFAULTS:
            return state.remove('transfer_defaults');

        case SET_POWERDOWN_DEFAULTS:
            return state.set('powerdown_defaults', fromJS(payload));

        case CLEAR_POWERDOWN_DEFAULTS:
            return state.remove('powerdown_defaults');

        case USERNAME_PASSWORD_LOGIN:
            return state; // saga

        case LOAD_SAVINGS_WITHDRAW:
            return state; // saga

        case SET_USERNAME:
            // TODO: Clean this up
            return state.mergeDeep({
                current: payload,
                show_login_modal: false,
                loginBroadcastOperation: undefined,
                loginDefault: undefined,
                logged_out: undefined,
            });

        case SET_USER:
            if (payload.vesting_shares)
                payload.vesting_shares = parseFloat(payload.vesting_shares);
            if (payload.delegated_vesting_shares)
                payload.delegated_vesting_shares = parseFloat(
                    payload.delegated_vesting_shares
                );
            if (payload.received_vesting_shares)
                payload.received_vesting_shares = parseFloat(
                    payload.received_vesting_shares
                );
            return state.mergeDeep({
                current: payload,
                show_login_modal: false,
                loginBroadcastOperation: undefined,
                loginDefault: undefined,
                logged_out: undefined,
            });

        case CLOSE_LOGIN:
            return state.merge({
                login_error: undefined,
                show_login_modal: false,
                loginBroadcastOperation: undefined,
                loginDefault: undefined,
            });

        case LOGIN_ERROR:
            return state.merge({
                login_error: payload.error,
                logged_out: undefined,
            });

        case LOGOUT:
            return defaultState.merge({ logged_out: true });

        case SHOW_SIGN_UP:
            return state.set('show_signup_modal', true);

        case HIDE_SIGN_UP:
            return state.set('show_signup_modal', false);

        case KEYS_ERROR:
            return state.merge({ keys_error: payload.error });

        case ACCOUNT_AUTH_LOOKUP:
            // AuthSaga
            return state;

        case SET_AUTHORITY: {
            // AuthSaga
            const { accountName, auth, pub_keys_used } = payload;
            state = state.setIn(['authority', accountName], fromJS(auth));
            if (pub_keys_used)
                state = state.set('pub_keys_used', pub_keys_used);
            return state;
        }

        case HIDE_CONNECTION_ERROR_MODAL:
            return state.set('hide_connection_error_modal', true);

        case SET:
            return state.setIn(
                Array.isArray(payload.key) ? payload.key : [payload.key],
                fromJS(payload.value)
            );

        case SHOW_SIDE_PANEL:
            return state.set('show_side_panel', true);

        case HIDE_SIDE_PANEL:
            return state.set('show_side_panel', false);

        default:
            return state;
    }
}

// Action creators
export const showLogin = (payload) => ({
    type: SHOW_LOGIN,
    payload,
});

export const hideLogin = (payload) => ({
    type: HIDE_LOGIN,
    payload,
});

export const showTerms = (payload) => ({
    type: SHOW_TERMS,
    payload,
});

export const acceptTerms = () => ({ type: ACCEPT_TERMS });

export const saveLoginConfirm = (payload) => ({
    type: SAVE_LOGIN_CONFIRM,
    payload,
});

export const saveLogin = (payload) => ({
    type: SAVE_LOGIN,
    payload,
});

export const removeHighSecurityKeys = (payload) => ({
    type: REMOVE_HIGH_SECURITY_KEYS,
    payload,
});

export const changeLanguage = (payload) => ({
    type: CHANGE_LANGUAGE,
    payload,
});

export const showTransfer = (payload) => ({
    type: SHOW_TRANSFER,
    payload,
});

export const showDecodeMemo = (payload) => ({
    type: SHOW_DECODE_MEMO,
    payload,
});

export const hideTransfer = (payload) => ({
    type: HIDE_TRANSFER,
    payload,
});

export const hideDecodeMemo = (payload) => ({
    type: HIDE_DECODE_MEMO,
    payload,
});

export const setMemoMessage = (payload) => ({
    type: SET_MEMO_MESSAGE,
    payload,
});

export const showPowerdown = (payload) => ({
    type: SHOW_POWERDOWN,
    payload,
});

export const hidePowerdown = (payload) => ({
    type: HIDE_POWERDOWN,
    payload,
});

export const setTransferDefaults = (payload) => ({
    type: SET_TRANSFER_DEFAULTS,
    payload,
});

export const clearTransferDefaults = (payload) => ({
    type: CLEAR_TRANSFER_DEFAULTS,
    payload,
});

export const setPowerdownDefaults = (payload) => ({
    type: SET_POWERDOWN_DEFAULTS,
    payload,
});

export const clearPowerdownDefaults = (payload) => ({
    type: CLEAR_POWERDOWN_DEFAULTS,
    payload,
});

export const usernamePasswordLogin = (payload) => ({
    type: USERNAME_PASSWORD_LOGIN,
    payload,
});

export const setUsername = (payload) => ({
    type: SET_USERNAME,
    payload,
});

export const setUser = (payload) => ({
    type: SET_USER,
    payload,
});

export const closeLogin = (payload) => ({
    type: CLOSE_LOGIN,
    payload,
});

export const loginError = (payload) => ({
    type: LOGIN_ERROR,
    payload,
});

export const logout = (payload) => ({
    type: LOGOUT,
    payload,
});

export const showSignUp = (payload) => ({
    type: SHOW_SIGN_UP,
    payload,
});

export const hideSignUp = (payload) => ({
    type: HIDE_SIGN_UP,
    payload,
});

export const keysError = (payload) => ({
    type: KEYS_ERROR,
    payload,
});

export const accountAuthLookup = (payload) => ({
    type: ACCOUNT_AUTH_LOOKUP,
    payload,
});

export const setAuthority = (payload) => ({
    type: SET_AUTHORITY,
    payload,
});

export const setLatestFeedPrice = (payload) => ({
    type: SET_LATEST_FEED_PRICE,
    payload,
});

export const hideConnectionErrorModal = (payload) => ({
    type: HIDE_CONNECTION_ERROR_MODAL,
    payload,
});

export const set = (payload) => ({
    type: SET,
    payload,
});

export const loadSavingsWithdraw = (payload) => ({
    type: LOAD_SAVINGS_WITHDRAW,
    payload,
});

export const showSidePanel = () => ({
    type: SHOW_SIDE_PANEL,
});

export const hideSidePanel = () => {
    return {
        type: HIDE_SIDE_PANEL,
    };
};

export const getVestingDelegations = (payload) => {
    return {
        type: GET_VESTING_DELEGATIONS,
        payload,
    };
};

export const setVestingDelegations = (payload) => ({
    type: SET_VESTING_DELEGATIONS,
    payload,
});
export const vestingDelegationsLoading = (payload) => ({
    type: VESTING_DELEGATIONS_LOADING,
    payload,
});
