import { handleAPIError } from './error.js';
import { receiveCategory, requestCategory } from './categories.js';
import { receiveRule, requestRule } from './rules.js';
import { CATEGORY_TYPE, RULE_TYPE } from '../constants.js';

export const MARK_SECTION_READ = 'MARK_SECTION_READ';
export const SELECT_SAVED = 'SELECT_SAVED';

export const selectSaved = () => ({ type: SELECT_SAVED });

export const markSectionRead = section => ({
  type: MARK_SECTION_READ,
  section,
});

const markCategoryRead = (category, token) => {
  return (dispatch, getState) => {
    dispatch(requestCategory(category));

    const { rules } = getState();
    const categoryRules = Object.values({ ...rules.items }).filter(rule => {
      return rule.category === category.id;
    });
    const ruleMapping = {};

    categoryRules.forEach(rule => {
      ruleMapping[rule.id] = { ...rule };
    });

    const url = `/api/categories/${category.id}/read/`;
    const options = {
      method: 'POST',
      headers: {
        'X-CSRFToken': token,
      },
    };

    return fetch(url, options)
      .then(response => response.json())
      .then(updatedCategory => {
        dispatch(receiveCategory({ ...updatedCategory }));
        return dispatch(
          markSectionRead({
            ...category,
            ...updatedCategory,
            rules: ruleMapping,
            type: CATEGORY_TYPE,
          })
        );
      })
      .catch(error => {
        dispatch(receiveCategory({}));
        dispatch(handleAPIError(error));
      });
  };
};

const markRuleRead = (rule, token) => {
  return (dispatch, getState) => {
    dispatch(requestRule(rule));

    const url = `/api/rules/${rule.id}/read/`;
    const options = {
      method: 'POST',
      headers: {
        'X-CSRFToken': token,
      },
    };

    return fetch(url, options)
      .then(response => response.json())
      .then(updatedRule => {
        dispatch(receiveRule({ ...updatedRule }));

        // Use the old rule to decrement category with old unread count
        dispatch(markSectionRead({ ...rule, type: RULE_TYPE }));
      })
      .catch(error => {
        dispatch(receiveRule({}));
        dispatch(handleAPIError(error));
      });
  };
};

export const markRead = (section, token) => {
  switch (section.type) {
    case RULE_TYPE:
      return markRuleRead(section, token);
    case CATEGORY_TYPE:
      return markCategoryRead(section, token);
  }
};
