import { requestRules, receiveRules, fetchRulesByCategory } from './rules.js';
import { handleAPIError } from './error.js';

import { CATEGORY_TYPE } from '../constants.js';

export const SELECT_CATEGORY = 'SELECT_CATEGORY';

export const RECEIVE_CATEGORY = 'RECEIVE_CATEGORY';
export const RECEIVE_CATEGORIES = 'RECEIVE_CATEGORIES';

export const REQUEST_CATEGORY = 'REQUEST_CATEGORY';
export const REQUEST_CATEGORIES = 'REQUEST_CATEGORIES';

export const selectCategory = category => ({
  type: SELECT_CATEGORY,
  section: { ...category, type: CATEGORY_TYPE },
});

export const receiveCategory = category => ({
  type: RECEIVE_CATEGORY,
  category,
});

export const receiveCategories = categories => ({
  type: RECEIVE_CATEGORIES,
  categories,
});

export const requestCategory = () => ({ type: REQUEST_CATEGORY });
export const requestCategories = () => ({ type: REQUEST_CATEGORIES });

export const fetchCategory = category => {
  return (dispatch, getState) => {
    const { selected } = getState();
    const selectedSection = { ...selected.item };

    if (selectedSection.type === CATEGORY_TYPE && selectedSection.clicks <= 1) {
      return;
    }

    dispatch(requestCategory());

    return fetch(`/api/categories/${category.id}`)
      .then(response => response.json())
      .then(json => {
        dispatch(receiveCategory({ ...json }));

        if (category.unread === 0) {
          return dispatch(fetchRulesByCategory(category));
        }
      })
      .catch(error => {
        dispatch(receiveCategory({}));
        dispatch(handleAPIError(error));
      });
  };
};

export const fetchCategories = () => {
  return dispatch => {
    dispatch(requestCategories());

    return fetch('/api/categories/')
      .then(response => response.json())
      .then(categories => {
        dispatch(receiveCategories(categories));

        return categories;
      })
      .then(categories => {
        dispatch(requestRules());

        const promises = categories.map(category => {
          return fetch(`/api/categories/${category.id}/rules/`);
        });

        return Promise.all(promises);
      })
      .then(responses => Promise.all(responses.map(response => response.json())))
      .then(nestedRules => dispatch(receiveRules(nestedRules.flat())))
      .catch(error => {
        dispatch(receiveCategories([]));
        dispatch(receiveRules([]));
        dispatch(handleAPIError(error));
      });
  };
};
