import React from 'react';
import Immutable from 'immutable';
import { ReduceStore } from 'flux/utils';
import { ActionTypes } from 'constants/Common';
import dispatcher from 'dispatcher';

class UIStore extends ReduceStore {
    getInitialState() {
        return new Immutable.Map();
    }

    reduce(state, action) {
        const { type, data } = action;

        switch (type) {
            case ActionTypes.EDIT_USER:
                return state.set(
                    this.getKey('edit_user', data.props.id),
                    data
                );

            case ActionTypes.USER_EDITED:
                return state.remove(
                    this.getKey('edit_user', data.id)
                );

            case ActionTypes.EDIT_DEPARTMENT:
                return state.set(
                    this.getKey('edit_department', data.id),
                    data
                );

            case ActionTypes.DEPARTMENT_EDITED:
                return state.remove(
                    this.getKey('edit_department', data.id)
                );

            case ActionTypes.EDIT_GROUP:
                return state.set(
                    this.getKey('edit_group', data.id),
                    data
                );

            case ActionTypes.GROUP_EDITED:
                return state.remove(
                    this.getKey('edit_group', data.id)
                );

            case ActionTypes.EDIT_GROUP_MEMBERS:
                return state.set(
                    this.getKey('edit_group_members', data.id, data.type),
                    data
                );

            case ActionTypes.SELECT_GROUP_MEMBERS:
                return state.set(
                    this.getKey('select_group_members', data.id, data.type),
                    data
                );

            case ActionTypes.GROUP_MEMBERS_EDITED:
                return state
                    .remove(this.getKey('edit_group_members', data.id, data.type))
                    .remove(this.getKey('select_group_members', data.id, data.type));

            case ActionTypes.EDIT_ORGANIZATION_ADMINS:
                return state.set(
                    this.getKey('edit_organization_admins'),
                    true
                );

            case ActionTypes.SELECT_ORGANIZATION_ADMINS:
                return state.set(
                    this.getKey('select_organization_admins'),
                    data
                );

            case ActionTypes.ORGANIZATION_ADMINS_EDITED:
                return state
                    .remove(this.getKey('edit_organization_admins'))
                    .remove(this.getKey('select_organization_admins'));

            case ActionTypes.EDIT_ORGANIZATION_PROFILE:
                return state.set(
                    this.getKey('edit_organization_profile'),
                    data
                );

            case ActionTypes.ORGANIZATION_PROFILE_EDITED:
                return state.remove(this.getKey('edit_organization_profile'));

            case ActionTypes.TYPE_NEW_DOMAIN:
                return state.set(
                    this.getKey('type_new_domain'),
                    data
                );

            case ActionTypes.SUGGEST_LIST_OPEN:
                return state.set(
                    this.getKey('suggest_list_open', data.id),
                    true
                );

            case ActionTypes.SUGGEST_LIST_CLOSED:
                return state.remove(
                    this.getKey('suggest_list_open', data.id)
                );

            case ActionTypes.TRANSITION_COMPLETED:
                return state.clear();

            case ActionTypes.START_SETTINGS_PROCESS:
                return state.set('isSettingsLoading', true);

            case ActionTypes.END_SETTINGS_PROCESS:
                return state.set('isSettingsLoading', false);

            case ActionTypes.ADD_STATUS_BAR:
                return state.set('status_bar', data);

            case ActionTypes.CLEAR_STATUS_BAR:
                return state.set('status_bar', null);
        }

        return state;
    }

    get(...keyComponents) {
        return this._state.get(this.getKey.apply(this, keyComponents));
    }

    getUserCard(id) {
        return this.getComponent('edit_user', id);
    }

    getEditedDepartment(id) {
        return this.getSubstate('edit_department', id);
    }

    getEditedGroup(id) {
        return this.getSubstate('edit_group', id);
    }

    getOrgProfileCard() {
        return this.getComponent('edit_organization_profile');
    }

    getComponent(type, id) {
        const data = this._state.get(this.getKey(type, id));

        if (data) {
            const Component = data.component;
            const props = data.props;

            return <Component {...props} />;
        }

        return null;
    }

    isGroupListEditable({ type, id }) {
        const key = this.getKey('edit_group_members', id, type);

        return Boolean(this._state.get(key));
    }

    getSelectedGroupMembers(id, type) {
        const key = this.getKey('select_group_members', id, type);
        const data = this._state.get(key);

        if (data) {
            return data.list;
        }
    }

    isOrganizationAdminListEditable() {
        const key = this.getKey('edit_organization_admins');

        return Boolean(this._state.get(key));
    }

    getSelectedOrganizationAdmins() {
        const key = this.getKey('select_organization_admins');
        const data = this._state.get(key);

        if (data) {
            return data.list;
        }
    }

    getTypedNewDomain() {
        const data = this._state.get(this.getKey('type_new_domain'));

        if (data) {
            return data.text;
        }
    }

    getSubstate(type, id) {
        return this._state.get(this.getKey(type, id));
    }

    getKey(...keyComponents) {
        return keyComponents.filter(Boolean).join('/');
    }

    getStatusBarData() {
        return this._state.get(this.getKey('status_bar'));
    }
}

export default window.ya.connect.UIStore = new UIStore(dispatcher);
