// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

import React from 'react';
import moment from 'moment';
import app from '../../../app';
import ActionTypes from './actiontypes';
import {toast} from "react-toastify";

const initialState = {
  notifications: [],
  notificationCenterVisible: false,
  selectedNotificationFilter: 'all',
  permanentNotificationVisible: false,
  permanentNotificationMessage: ''
};

let counter = 0;
const validNotificationTypes = ['success', 'error', 'info'];
const validFilters = ['all', 'success', 'error', 'info'];

function addNotification ({ notifications }, info) {
  const newNotifications = notifications.slice();
  info = { ...info };
  info.toastId = ++counter;
  info.time = moment();
  info.cleanMsg = app.utils.stripHTML(info.msg);

  if (info.escape !== true && info.escape !== false) {
    info.escape = true;
  }

  // clear: true causes all visible messages to be hidden
  if (info.clear) {
    const idsToClear = _.map(notifications, 'toastId');

    // Add some delay to prevent weird flickering
    setTimeout(() => {
      idsToClear.forEach(id => toast.dismiss(id));
    }, 800);
  }

  newNotifications.unshift(info);

  toast(<span>{info.msg}</span>, info);

  return newNotifications;
}

function clearNotification({ notifications }, toastId) {
  const idx = notifications.findIndex(el => {
    return el.toastId === toastId;
  });
  if (idx === -1) {
    // no changes
    return notifications;
  }

  const newNotifications = [].concat(notifications);
  newNotifications.splice(idx, 1);

  toast.dismiss(toastId);

  return newNotifications;
}

export default function notifications(state = initialState, action) {
  const { options, type } = action;
  switch (type) {

    case ActionTypes.ADD_NOTIFICATION:
      if (!validNotificationTypes.includes(options.info.type)) {
        return state;
      }
      return {
        ...state,
        notifications: addNotification(state, options.info)
      };

    case ActionTypes.CLEAR_ALL_NOTIFICATIONS:
      toast.dismiss();
      return {
        ...state,
        notifications: []
      };

    case ActionTypes.CLEAR_SINGLE_NOTIFICATION:
      return {
        ...state,
        notifications: clearNotification(state, options.toastId)
      };

    case ActionTypes.SHOW_NOTIFICATION_CENTER:
      return {
        ...state,
        notificationCenterVisible: true
      };

    case ActionTypes.HIDE_NOTIFICATION_CENTER:
      return {
        ...state,
        notificationCenterVisible: false
      };

    case ActionTypes.SELECT_NOTIFICATION_FILTER:
      if (!validFilters.includes(options.filter)) {
        return state;
      }
      return {
        ...state,
        selectedNotificationFilter: options.filter
      };

    case ActionTypes.SHOW_PERMANENT_NOTIFICATION:
      return {
        ...state,
        permanentNotificationVisible: true,
        permanentNotificationMessage: options.msg
      };

    case ActionTypes.HIDE_PERMANENT_NOTIFICATION:
      return {
        ...state,
        permanentNotificationVisible: false
      };

    default:
      return state;
  }
}
