import { actionTypes } from 'constants/action-types';
import { getAllCallbackKeys, getDataContainerCallbackKeys } from 'utils/component';

export type CallBackState = {
  callbackKeys: {
    filter: {
      [x: string]: any;
    };
    data: {
      [x: string]: any;
    };
    interaction: {
      [x: string]: any;
    };
  };
  callbackValues: {
    [x: string]: any;
  };
};

export function emitCallback(id, callbackValue) {
  return async (dispatch) => {
    dispatch({
      type: actionTypes.CALLBACK_EMIT,
      payload: {
        id,
        callbackValue,
      },
    });
  };
}

const initialState = {
  callbackKeys: {
    filter: {},
    data: {},
    interaction: {},
  },
  callbackValues: {},
};

export default function reducer(state = initialState, { type, payload }): CallBackState {
  switch (type) {
    // 数据容器相关回调key 记录下来
    case actionTypes.CALLBACKS_DATA_CONTAINER_INIT: {
      const { dataContainers, filters } = payload;
      const callbackKeys = getDataContainerCallbackKeys(dataContainers, filters);
      const { filter, data } = callbackKeys;
      return {
        ...state,
        callbackKeys: {
          ...state.callbackKeys,
          filter: {
            ...state.callbackKeys.filter,
            ...filter,
          },
          data: {
            ...state.callbackKeys.data,
            ...data,
          },
        },
      };
    }
    case actionTypes.CALLBACKS_INIT: {
      const { components, filters } = payload;
      const callbackKeys = getAllCallbackKeys(components, filters);
      return {
        ...state,
        callbackKeys: {
          ...state.callbackKeys,
          filter: {
            ...state.callbackKeys.filter,
            ...callbackKeys.filter,
          },
          data: {
            ...state.callbackKeys.data,
            ...callbackKeys.data,
          },
          interaction: {
            ...state.callbackKeys.interaction,
            ...callbackKeys.interaction,
          },
        },
      };
    }

    case actionTypes.CALLBACK_EMIT: {
      const { id, callbackValue } = payload;
      let callbackKeys = state.callbackKeys;
      if (id) {
        const oldKeys = state.callbackKeys.interaction[id] || [];
        const keys = Object.keys(callbackValue).filter((d) => d);
        const newKeys = Array.from(new Set(oldKeys.concat(keys)));
        callbackKeys = {
          ...state.callbackKeys,
          interaction: {
            ...state.callbackKeys.interaction,
            [id]: newKeys,
          },
        };
      }
      return {
        ...state,
        callbackKeys,
        callbackValues: {
          ...state.callbackValues,
          ...payload.callbackValue,
        },
      };
    }

    default:
      return state;
  }
}
