const {ipcRenderer} = require('electron')
const log = require('electron-log')
import { ON_GETH_SERVER_DISCONNECTED, ON_GETH_SERVER_CONNECTED, BULK_SYNC_FINISHED, BULK_SYNC_STARTED, ERROR_NOTIFICATION, INFO_NOTIFICATION, ON_UI_SERVER_CONNECTED, ON_UI_SERVER_DISCONNECTED, REQUEST_CONFIG_RESPONSE, LATEST_SYNCED_BLOCK, LATEST_SYNCED_GETH_BLOCK, ON_SERVER_CONNECTED, ON_SERVER_DISCONNECTED, PEER_COUNT_DATA, GETH_FINISHED_SYNCING, RUNNING_FAILURE, BULK_ORPHANS_CHECK_STARTED, BULK_ORPHANS_CHECK_FINISHED } from '../utils/constants'
import { initializeConfiguration } from './app/actions/configuration'
import { updateGethBlockInfo, clearGethBlockInfo, updateAugurNodeBlockInfo, clearAugurNodeBlockInfo } from './app/actions/blockInfo'
import { updateServerAttrib } from './app/actions/serverStatus'
import { addInfoNotification, addErrorNotification } from './app/actions/notifications'
import { startAugurNode, stopAugurNode, stopGethNode } from './app/actions/local-server-cmds'
import store from './store'

export const handleEvents = () => {

  let stallChecker = null

  ipcRenderer.on('ready', () => {
    log.info('app is ready')
  })

  ipcRenderer.on(REQUEST_CONFIG_RESPONSE, (event, config) => {
    store.dispatch(initializeConfiguration(config))
  })

  ipcRenderer.on(LATEST_SYNCED_BLOCK, (event, info) => {
    if (info && info.lastSyncBlockNumber) {
      store.dispatch(updateServerAttrib({ AUGUR_NODE_SYNCING: true }))
    }
    store.dispatch(updateAugurNodeBlockInfo(info))
  })

  ipcRenderer.on(LATEST_SYNCED_GETH_BLOCK, (event, info) => {
    store.dispatch(updateGethBlockInfo(info))
  })

  ipcRenderer.on(ON_SERVER_CONNECTED, () => {
    store.dispatch(updateServerAttrib({ AUGUR_NODE_CONNECTED: true, CONNECTING: false }))

    if (store.getState().serverStatus.DISCONNECT_REQUESTED) {
      stopAugurNode()
      store.dispatch(updateServerAttrib({ DISCONNECT_REQUESTED: false }))
    }
  })

  ipcRenderer.on(ON_SERVER_DISCONNECTED, () => {
    store.dispatch(updateServerAttrib({ AUGUR_NODE_CONNECTED: false, CONNECTING: false, AUGUR_NODE_SYNCING: false }))
    // clear block info
    store.dispatch(clearAugurNodeBlockInfo())
    clearInterval(stallChecker)
  })

  ipcRenderer.on(ON_GETH_SERVER_CONNECTED, () => {
    store.dispatch(updateServerAttrib({ GETH_CONNECTED: true, GETH_INITIATED: true, CONNECTING: false, GETH_FINISHED_SYNCING: false }))
    if (store.getState().serverStatus.DISCONNECT_REQUESTED) {
      stopGethNode()
      store.dispatch(updateServerAttrib({ DISCONNECT_REQUESTED: false }))
    }
  })

  ipcRenderer.on(ON_GETH_SERVER_DISCONNECTED, () => {
    store.dispatch(updateServerAttrib({ GETH_CONNECTED: false, CONNECTING: false }))
    // clear block info
    store.dispatch(clearGethBlockInfo())
  })

  ipcRenderer.on(ON_UI_SERVER_CONNECTED, () => {
    store.dispatch(updateServerAttrib({ UI_SERVER_CONNECTED: true }))
  })

  ipcRenderer.on(ON_UI_SERVER_DISCONNECTED, () => {
    store.dispatch(updateServerAttrib({ UI_SERVER_DISCONNECTED: false }))
  })

  ipcRenderer.on(PEER_COUNT_DATA, (event, data) => {
    store.dispatch(updateServerAttrib({ PEER_COUNT_DATA: data.peerCount }))
    if (!store.getState().serverStatus.GETH_FINISHED_SYNCING) {
      store.dispatch(updateServerAttrib({ GETH_SYNCING: data.peerCount > 0 ? true : false }))
    }
  })

  ipcRenderer.on(GETH_FINISHED_SYNCING, () => {
    if (store.getState().serverStatus.GETH_INITIATED) {
      startAugurNode()
    }
    store.dispatch(updateServerAttrib({ GETH_FINISHED_SYNCING: true, GETH_INITIATED: false, GETH_SYNCING: false }))
  })

  ipcRenderer.on(BULK_SYNC_STARTED, () => {
    store.dispatch(updateServerAttrib({ AUGUR_BULK_SYNCING: true }))
  })

  ipcRenderer.on(BULK_SYNC_FINISHED, () => {
    store.dispatch(updateServerAttrib({ AUGUR_BULK_SYNCING: false }))
  })

  ipcRenderer.on(BULK_ORPHANS_CHECK_STARTED, () => {
    store.dispatch(updateServerAttrib({ AUGUR_BULK_ORPHANS_CHECK: true }))
  })

  ipcRenderer.on(BULK_ORPHANS_CHECK_FINISHED, () => {
    store.dispatch(updateServerAttrib({ AUGUR_BULK_ORPHANS_CHECK: false }))
  })

  ipcRenderer.on(INFO_NOTIFICATION, (event, notification) => {
    setTimeout(() => {
      store.dispatch(addInfoNotification(notification))
    }, 500)
    log.info('INFO_NOTIFICATION', notification)
  })

  ipcRenderer.on(ERROR_NOTIFICATION, (event, notification) => {
    store.dispatch(addErrorNotification(notification))

    log.info('ERROR_NOTIFICATION', notification)
  })

}
