import { createSyncAction, createAsyncAction } from 'utils/actions';
import { standardWidgetAction } from './widgets';
import { fetchCalendar } from 'services/calendarapi';
import { getWidgetById } from 'utils/workspaces';

// ********* CALENDAR WIDGET ACTIONS ********* //

// Calendar action definitions

export const CALENDAR_CHANGE_PARAMETERS = 'CALENDAR_CHANGE_PARAMETERS';
const changeCalendarParameters = createSyncAction(
  CALENDAR_CHANGE_PARAMETERS, (widgetId, newParameters) => {
    bzTrack.track('Calendar: Changed Filters', {
      newParameters: newParameters
    });

    const swa = standardWidgetAction(widgetId, {
      parameters: newParameters
    });
    return swa;
  }
);

export const CALENDAR_CHANGE_DISPLAY_OPTIONS = 'CALENDAR_CHANGE_DISPLAY_OPTIONS';
const changeCalendarDisplayOptions = createSyncAction(
  CALENDAR_CHANGE_DISPLAY_OPTIONS, (widgetId, newDispOpts) => {
    bzTrack.track('Calendar: Changed Filters', {
      displayOptions: newDispOpts
    });

    return standardWidgetAction(widgetId, {
      displayOptions: newDispOpts
    });
  }
);

// Fetch events from calendar endpoint and update the widget
export const LOADING_CALENDAR = 'LOADING_CALENDAR';
const loadCalendarEvents = createAsyncAction(LOADING_CALENDAR, (widgetId, parameters) => {
  return fetchCalendar(parameters).then(events =>
      standardWidgetAction(widgetId, {
        page: parameters.page,
        events
      })
  );
}, standardWidgetAction);


// ********* CALENDAR WIDGET ACTION CREATORS ********* //

// Load a new calendar
export function loadNewCalendar(widgetId, parameters = null) {
  return (dispatch, getState) => {
    if (parameters) {
      parameters.page = 0;
    }
    dispatch(changeCalendarParameters(widgetId, parameters));
    const calendar = getWidgetById(widgetId, getState());
    if (calendar) {
      dispatch(loadCalendarEvents(widgetId, calendar.getIn(['data', 'parameters'])));
    }
  };
}

// Load more events for some calendar
export function loadMoreCalendarEvents(widgetId) {
  return (dispatch, getState) => {
    // Use the parameters from the widget itself
    const calendar = getWidgetById(widgetId, getState());
    if (!calendar) {
      /* eslint-disable no-console */
      console.error('Could not load more events for calendar widget with id ', widgetId,
      ' since it doesn\'t exist');
      /* eslint-enable no-console */
      return dispatch;
    }
    let parameters = calendar.getIn(['data', 'parameters']);
    // Look for the next page of results
    parameters = parameters.update('page', page => page + 1);
    dispatch(loadCalendarEvents(widgetId, parameters));
  };
}

// Load a new type of calendar
export function loadNewCalendarType(widgetId, oldParameters, newType) {
  const parameters = {
    calendarType: newType,
    symbol: oldParameters.symbol
  };
  return loadNewCalendar(widgetId, parameters);
}

// Load a calendar with new dates
export function loadNewCalendarDates(widgetId, parameters, newStart, newEnd) {
  parameters.dateStart = newStart;
  parameters.dateEnd = newEnd;
  return loadNewCalendar(widgetId, parameters);
}

// change sort of calendar
export function changeCalendarSort(widgetId, displayOptions, newSort) {
  displayOptions.colSortDirs = newSort;
  return (dispatch, getState) => {
    return dispatch(changeCalendarDisplayOptions(widgetId, displayOptions));
  };
}

// change frozen columns (for horizontal scrolling)
export function freezeCalendarColumns(widgetId, displayOptions, newFreeze) {
  displayOptions.frozenColumns = newFreeze;
  return (dispatch, getState) => {
    return dispatch(changeCalendarDisplayOptions(widgetId, displayOptions));
  };
}

// change displayed columns
export function changeCalendarColumns(widgetId, displayOptions, newCols) {
  displayOptions.colHidden = newCols;
  return (dispatch, getState) => {
    return dispatch(changeCalendarDisplayOptions(widgetId, displayOptions));
  };
}

// change displayed columns
export function changeCalendarWidths(widgetId, displayOptions, newWidths) {
  displayOptions.colWidths = newWidths;
  return (dispatch, getState) => {
    return dispatch(changeCalendarDisplayOptions(widgetId, displayOptions));
  };
}

// Load a calendar with a new symbol
export function loadNewCalendarSymbol(widgetId, oldParameters, newSymbol) {
  const parameters = {
    calendarType: oldParameters.calendarType,
    symbol: (newSymbol !== '' ? newSymbol : null),
  };

  if (parameters.calendarType === 'earnings') {
    // If earnings is searching for a symbol, search all dates
    if (parameters.symbol !== null) {
      parameters.dateStart = null;
      parameters.dateEnd = null;
    // If a search is beaing cleared and the user selected dates, keep them
    } else if (oldParameters.dateStart !== null || oldParameters.dateEnd !== null) {
      parameters.dateStart = oldParameters.dateStart;
      parameters.dateEnd = oldParameters.dateEnd;
    }
  // If this isn't an earnings calendar, keep dates
  } else {
    parameters.dateStart = oldParameters.dateStart;
    parameters.dateEnd = oldParameters.dateEnd;
  }

  return loadNewCalendar(widgetId, parameters);
}
