import { createAction } from 'redux-actions';
import { batchActions } from 'redux-batched-actions';
import { filterBuilderTypes, filterBuilderValueTypes, sortDirections } from 'Helpers/Props';
import { createThunk, handleThunks } from 'Store/thunks';
import createAjaxRequest from 'Utilities/createAjaxRequest';
import serverSideCollectionHandlers from 'Utilities/State/serverSideCollectionHandlers';
import translate from 'Utilities/String/translate';
import { set, updateItem } from './baseActions';
import createHandleActions from './Creators/createHandleActions';
import createRemoveItemHandler from './Creators/createRemoveItemHandler';
import createServerSideCollectionHandlers from './Creators/createServerSideCollectionHandlers';
import createClearReducer from './Creators/Reducers/createClearReducer';
import createSetTableOptionReducer from './Creators/Reducers/createSetTableOptionReducer';

//
// Variables

export const section = 'blocklist';

//
// State

export const defaultState = {
  isFetching: false,
  isPopulated: false,
  pageSize: 20,
  sortKey: 'date',
  sortDirection: sortDirections.DESCENDING,
  error: null,
  items: [],
  isRemoving: false,

  columns: [
    {
      name: 'series.sortTitle',
      label: () => translate('SeriesTitle'),
      isSortable: true,
      isVisible: true
    },
    {
      name: 'sourceTitle',
      label: () => translate('SourceTitle'),
      isSortable: true,
      isVisible: true
    },
    {
      name: 'languages',
      label: () => translate('Languages'),
      isVisible: false
    },
    {
      name: 'quality',
      label: () => translate('Quality'),
      isVisible: true
    },
    {
      name: 'customFormats',
      label: () => translate('Formats'),
      isSortable: false,
      isVisible: true
    },
    {
      name: 'date',
      label: () => translate('Date'),
      isSortable: true,
      isVisible: true
    },
    {
      name: 'indexer',
      label: () => translate('Indexer'),
      isSortable: true,
      isVisible: false
    },
    {
      name: 'actions',
      columnLabel: () => translate('Actions'),
      isVisible: true,
      isModifiable: false
    }
  ],

  selectedFilterKey: 'all',

  filters: [
    {
      key: 'all',
      label: () => translate('All'),
      filters: []
    }
  ],

  filterBuilderProps: [
    {
      name: 'seriesIds',
      label: () => translate('Series'),
      type: filterBuilderTypes.EQUAL,
      valueType: filterBuilderValueTypes.SERIES
    },
    {
      name: 'protocols',
      label: () => translate('Protocol'),
      type: filterBuilderTypes.EQUAL,
      valueType: filterBuilderValueTypes.PROTOCOL
    }
  ]
};

export const persistState = [
  'blocklist.pageSize',
  'blocklist.sortKey',
  'blocklist.sortDirection',
  'blocklist.selectedFilterKey',
  'blocklist.columns'
];

//
// Action Types

export const FETCH_BLOCKLIST = 'blocklist/fetchBlocklist';
export const GOTO_BLOCKLIST_PAGE = 'blocklist/gotoBlocklistPage';
export const SET_BLOCKLIST_SORT = 'blocklist/setBlocklistSort';
export const SET_BLOCKLIST_FILTER = 'blocklist/setBlocklistFilter';
export const SET_BLOCKLIST_TABLE_OPTION = 'blocklist/setBlocklistTableOption';
export const REMOVE_BLOCKLIST_ITEM = 'blocklist/removeBlocklistItem';
export const REMOVE_BLOCKLIST_ITEMS = 'blocklist/removeBlocklistItems';
export const CLEAR_BLOCKLIST = 'blocklist/clearBlocklist';

//
// Action Creators

export const fetchBlocklist = createThunk(FETCH_BLOCKLIST);
export const gotoBlocklistPage = createThunk(GOTO_BLOCKLIST_PAGE);
export const setBlocklistSort = createThunk(SET_BLOCKLIST_SORT);
export const setBlocklistFilter = createThunk(SET_BLOCKLIST_FILTER);
export const setBlocklistTableOption = createAction(SET_BLOCKLIST_TABLE_OPTION);
export const removeBlocklistItem = createThunk(REMOVE_BLOCKLIST_ITEM);
export const removeBlocklistItems = createThunk(REMOVE_BLOCKLIST_ITEMS);
export const clearBlocklist = createAction(CLEAR_BLOCKLIST);

//
// Action Handlers

export const actionHandlers = handleThunks({
  ...createServerSideCollectionHandlers(
    section,
    '/blocklist',
    fetchBlocklist,
    {
      [serverSideCollectionHandlers.FETCH]: FETCH_BLOCKLIST,
      [serverSideCollectionHandlers.EXACT_PAGE]: GOTO_BLOCKLIST_PAGE,
      [serverSideCollectionHandlers.SORT]: SET_BLOCKLIST_SORT,
      [serverSideCollectionHandlers.FILTER]: SET_BLOCKLIST_FILTER
    }),

  [REMOVE_BLOCKLIST_ITEM]: createRemoveItemHandler(section, '/blocklist'),

  [REMOVE_BLOCKLIST_ITEMS]: function(getState, payload, dispatch) {
    const {
      ids
    } = payload;

    dispatch(batchActions([
      ...ids.map((id) => {
        return updateItem({
          section,
          id,
          isRemoving: true
        });
      }),

      set({ section, isRemoving: true })
    ]));

    const promise = createAjaxRequest({
      url: '/blocklist/bulk',
      method: 'DELETE',
      dataType: 'json',
      contentType: 'application/json',
      data: JSON.stringify({ ids })
    }).request;

    promise.done((data) => {
      // Don't use batchActions with thunks
      dispatch(fetchBlocklist());

      dispatch(set({ section, isRemoving: false }));
    });

    promise.fail((xhr) => {
      dispatch(batchActions([
        ...ids.map((id) => {
          return updateItem({
            section,
            id,
            isRemoving: false
          });
        }),

        set({ section, isRemoving: false })
      ]));
    });
  }
});

//
// Reducers

export const reducers = createHandleActions({

  [SET_BLOCKLIST_TABLE_OPTION]: createSetTableOptionReducer(section),

  [CLEAR_BLOCKLIST]: createClearReducer(section, {
    isFetching: false,
    isPopulated: false,
    error: null,
    items: [],
    totalPages: 0,
    totalRecords: 0
  })

}, defaultState, section);
