import _ from 'lodash';
import Immutable from 'immutable';
import { ReduceStore } from 'flux/utils';
import { ActionTypes } from 'constants/Common';
import dispatcher from 'dispatcher';
import Department from 'records/Department';
import UserStore from 'stores/Users';

function compareByName(a, b) {
    const aName = a.toSortableString();
    const bName = b.toSortableString();

    if (aName === bName) {
        return 0;
    }

    return aName > bName ? 1 : -1;
}

class DepartmentStore extends ReduceStore {
    getInitialState() {
        return Immutable.fromJS({
            index: {}, flat_lists: {},
        });
    }

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

        switch (type) {
            case ActionTypes.RECEIVE_MIXED_DATA:
                return this._receiveRawData(state, data);
            case ActionTypes.RECEIVE_DEPARTMENT:
                return state.setIn(['index', data.id], data);
            case ActionTypes.DISCARD_DEPARTMENT:
                return state.removeIn(['index', data.id]);
            default:
                return state;
        }
    }

    /**
     * Возвращает отдел по его id
     * @method  get
     * @param   {Number} id
     * @returns {?Department}
     */
    get(id) {
        return this._state.getIn(['index', id]);
    }

    getAll() {
        const index = this._state.get('index');

        return (index ? index.toArray() : null) || [];
    }

    getList(filter) {
        let list = this.getAll();

        if (filter) {
            list = list.filter(filter);
        }

        return list.sort(compareByName);
    }

    getFlatMemberList(id) {
        const list = this._state.getIn(['flat_lists', id]);

        if (!list) {
            return [];
        }

        return list.toArray().map(userId => UserStore.get(userId));
    }

    getName(id) {
        const item = this.get(id);

        return item ? item.getName() : id;
    }

    _receiveRawData(state, data) {
        let nextState = state;

        if (data.departments) {
            const nextIndex = new Immutable.Map(data.departments)
                .map(item => Department.create(item));

            nextState = nextState.mergeIn(['index'], nextIndex);
        }

        const list = _.find(data.lists, { type: 'users' });

        if (data.tag === 'flat_department') {
            const id = _.get(list, 'query.recursive_department_id');

            if (id && list.order) {
                const nextList = new Immutable.List(list.order);

                nextState = nextState.mergeIn(['flat_lists'], new Immutable.Map([
                    [id, nextList],
                ]));
            }
        }

        return nextState;
    }
}

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