import { handleAPIError } from './error.js';
import { RULE_TYPE, CATEGORY_TYPE } from '../constants.js';

export const SELECT_POST = 'SELECT_POST';
export const UNSELECT_POST = 'UNSELECT_POST';

export const RECEIVE_POSTS = 'RECEIVE_POSTS';
export const RECEIVE_POST = 'RECEIVE_POST';
export const REQUEST_POSTS = 'REQUEST_POSTS';

export const MARK_POST_READ = 'MARK_POST_READ';
export const MARKING_POST = 'MARKING_POST';

export const MARK_POST_SAVED = 'MARK_POST_SAVED';
export const MARK_POST_UNSAVED = 'MARK_POST_UNSAVED';

export const TOGGLING_POST = 'TOGGLING_POST';
export const TOGGLED_POST = 'TOGGLED_POST';

export const requestPosts = () => ({ type: REQUEST_POSTS });
export const receivePost = post => ({ type: RECEIVE_POST, post });
export const receivePosts = (posts, next) => ({
  type: RECEIVE_POSTS,
  posts,
  next,
});

export const selectPost = post => ({ type: SELECT_POST, post });
export const unSelectPost = () => ({ type: UNSELECT_POST });

export const markingPostRead = () => ({ type: MARKING_POST });
export const postRead = (post, section) => ({
  type: MARK_POST_READ,
  post,
  section,
});

export const togglingPost = () => ({ type: TOGGLING_POST });
export const postToggled = post => ({ type: TOGGLED_POST, post });

export const markPostRead = (post, token) => {
  return (dispatch, getState) => {
    const { selected } = getState();

    dispatch(markingPostRead());

    const url = `/api/posts/${post.id}/`;
    const options = {
      method: 'PATCH',
      headers: {
        'Content-Type': 'application/json',
        'X-CSRFToken': token,
      },
      body: JSON.stringify({ read: true }),
    };

    const section = { ...selected.item };

    return fetch(url, options)
      .then(response => response.json())
      .then(updatedPost => {
        dispatch(receivePost({ ...updatedPost }));
        dispatch(postRead({ ...updatedPost }, section));
      })
      .catch(error => {
        dispatch(receivePost({}));
        dispatch(handleAPIError(error));
      });
  };
};

export const toggleSaved = (post, token) => {
  return (dispatch, getState) => {
    dispatch(togglingPost());

    const url = `/api/posts/${post.id}/`;
    const options = {
      method: 'PATCH',
      headers: {
        'Content-Type': 'application/json',
        'X-CSRFToken': token,
      },
      body: JSON.stringify({ saved: !post.saved }),
    };

    return fetch(url, options)
      .then(response => response.json())
      .then(updatedPost => {
        dispatch(receivePost({ ...updatedPost }));
        dispatch(postToggled({ ...updatedPost }));
      })
      .catch(error => {
        dispatch(receivePost({}));
        dispatch(handleAPIError(error));
      });
  };
};

export const fetchSavedPosts = (next = false) => {
  return dispatch => {
    dispatch(requestPosts());

    const url = next ? next : '/api/posts/?saved=true';

    return fetch(url)
      .then(response => response.json())
      .then(posts => dispatch(receivePosts(posts.results, posts.next)))
      .catch(error => {
        dispatch(receivePosts([]));
        dispatch(handleAPIError(error));
      });
  };
};

export const fetchPostsBySection = (section, next = false) => {
  return dispatch => {
    if (section.unread === 0) {
      return;
    }

    dispatch(requestPosts());

    let url = null;

    switch (section.type) {
      case RULE_TYPE:
        url = next ? next : `/api/rules/${section.id}/posts/`;
        break;
      case CATEGORY_TYPE:
        url = next ? next : `/api/categories/${section.id}/posts/`;
        break;
    }

    return fetch(url)
      .then(response => response.json())
      .then(posts => dispatch(receivePosts(posts.results, posts.next)))
      .catch(error => {
        dispatch(receivePosts([]));
        dispatch(handleAPIError(error));
      });
  };
};
