import { objectsFromArray } from '../../../utils.js';
import { CATEGORY_TYPE, RULE_TYPE } from '../constants.js';

import {
  MARKING_POST,
  MARK_POST_READ,
  RECEIVE_POST,
  RECEIVE_POSTS,
  REQUEST_POSTS,
  TOGGLING_POST,
  TOGGLED_POST,
} from '../actions/posts.js';
import { MARK_SECTION_READ } from '../actions/selected.js';

const sortOrdering = (firstPost, secondPost) => {
  const dateOrdering =
    new Date(firstPost.publicationDate) < new Date(secondPost.publicationDate);

  if (firstPost.read && !secondPost.read) {
    return 1;
  } else if (secondPost.read && !firstPost.read) {
    return -1;
  }

  return dateOrdering;
};

const defaultState = { items: [], isFetching: false, isUpdating: false };

export const posts = (state = { ...defaultState }, action) => {
  switch (action.type) {
    case REQUEST_POSTS:
      return { ...state, isFetching: true };
    case RECEIVE_POST:
      const postIndex = state.items.findIndex(post => post.id === action.post.id);
      let newItems = [...state.items];

      if (postIndex >= 0) {
        newItems.splice(postIndex, 1, { ...action.post });
      } else {
        newItems = [...state.items, { ...action.post }];
      }

      newItems.sort(sortOrdering);

      return {
        ...state,
        items: newItems,
      };
    case RECEIVE_POSTS:
      const receivedPosts = objectsFromArray(action.posts, 'id');

      let mergedPosts = { ...objectsFromArray(state.items, 'id'), ...receivedPosts };
      let sortedPosts = Object.values(mergedPosts).sort(sortOrdering);

      return {
        ...state,
        isFetching: false,
        items: sortedPosts,
      };
    case MARK_SECTION_READ:
      let posts = [];

      switch (action.section.type) {
        case CATEGORY_TYPE:
          posts = [...state.items];

          posts.forEach(post => {
            if (!(post.rule.id in { ...action.section.rules })) return;

            post.read = true;
          });

          break;
        case RULE_TYPE:
          posts = [...state.items];

          posts.forEach(post => {
            if (post.rule.id != action.section.id) return;

            post.read = true;
          });

          break;
      }

      return {
        ...state,
        items: posts,
      };
    case MARKING_POST:
      return { ...state, isUpdating: true };
    case TOGGLING_POST:
      return { ...state, isUpdating: true };
    case MARK_POST_READ:
      return { ...state, isUpdating: false };
    case TOGGLED_POST:
      return { ...state, isUpdating: false };
    default:
      return state;
  }
};
