import React, { useEffect } from 'react'
import createScheduler from '@zap/utils/scheduler'
import PropTypes from 'prop-types'
import Activity from 'containers/Activity'
import Wallet from 'containers/Wallet'
import { MainContent } from 'components/UI'

// Bitcoin blocks come on average every 10 mins
// but we poll a lot more frequently to make UI a little bit more responsive
const TX_REFETCH_INTERVAL = 1000 * 60 * 1

// Refresh autopilot scores every hour.
const AUTOPILOT_SCORES_REFRESH_INTERVAL = 1000 * 60 * 60

// Initial re-fetch after 2 seconds.
const INITIAL_REFETCH_INTERVAL = 2000

// Fetch node data no less than once every 10 minutes.
const MAX_REFETCH_INTERVAL = 1000 * 60 * 10

// Amount to increment re-fetch timer by after each fetch.
const BACKOFF_SCHEDULE = 1.5

// App scheduler / polling service
const appScheduler = createScheduler()

function App({
  isAppReady,
  modals,
  payReq,
  updateAutopilotNodeScores,
  fetchActivityHistory,
  setIsWalletOpen,
  fetchPeers,
  fetchTransactions,
  setModals,
}) {
  /**
   * App scheduler / polling service setup. Add new app-wide polls here
   */
  useEffect(() => {
    /**
     * Fetch node data on an exponentially incrementing backoff schedule so that when the app is first mounted, we fetch
     * node data quite frequently but as time goes on the frequency is reduced down to a maximum of MAX_REFETCH_INTERVAL
     */
    appScheduler.addTask({
      task: fetchPeers,
      taskId: 'fetchPeers',
      baseDelay: INITIAL_REFETCH_INTERVAL,
      maxDelay: MAX_REFETCH_INTERVAL,
      backoff: BACKOFF_SCHEDULE,
    })

    appScheduler.addTask({
      task: fetchTransactions,
      taskId: 'fetchTransactions',
      baseDelay: TX_REFETCH_INTERVAL,
    })

    appScheduler.addTask({
      task: updateAutopilotNodeScores,
      taskId: 'updateAutopilotNodeScores',
      baseDelay: AUTOPILOT_SCORES_REFRESH_INTERVAL,
    })

    return () => {
      appScheduler.removeAllTasks()
    }
  }, [fetchPeers, fetchTransactions, updateAutopilotNodeScores])

  useEffect(() => {
    // Set wallet open state.
    setIsWalletOpen(true)
    // fetch data from lnd.
    fetchActivityHistory()
    // fetch node info.
    fetchPeers()
    // Update autopilot node scores.
    updateAutopilotNodeScores()
  }, [fetchActivityHistory, fetchPeers, setIsWalletOpen, updateAutopilotNodeScores])

  // Open the pay form when a payment link is used.
  useEffect(() => {
    if (isAppReady && payReq) {
      if (!modals.find(m => m.type === 'PAY_FORM')) {
        setModals([{ type: 'PAY_FORM' }])
      }
    }
  }, [payReq, isAppReady, modals, setModals])

  if (!isAppReady) {
    return null
  }

  return (
    <MainContent>
      <Wallet />
      <Activity />
    </MainContent>
  )
}

App.propTypes = {
  fetchActivityHistory: PropTypes.func.isRequired,
  fetchPeers: PropTypes.func.isRequired,
  fetchTransactions: PropTypes.func.isRequired,
  isAppReady: PropTypes.bool.isRequired,
  modals: PropTypes.array.isRequired,
  payReq: PropTypes.object,
  setIsWalletOpen: PropTypes.func.isRequired,
  setModals: PropTypes.func.isRequired,
  updateAutopilotNodeScores: PropTypes.func.isRequired,
}

export default App

@@ -539,17 +539,18 @@
 h after 
-2
+30
  seconds
@@ -557,16 +557,22 @@
 .%0Aconst 
+PEERS_
 INITIAL_
@@ -594,12 +594,17 @@
 L = 
-2
+1
 000
+ * 30
 %0A%0A//
@@ -606,28 +606,34 @@
 0%0A%0A// Fetch 
-node
+peers list
  data no les
@@ -668,16 +668,22 @@
 .%0Aconst 
+PEERS_
 MAX_REFE
@@ -778,16 +778,30 @@
 .%0Aconst 
+PEERS_REFETCH_
 BACKOFF_
@@ -815,11 +815,9 @@
 E = 
-1.5
+2
 %0A%0A//
@@ -1379,21 +1379,16 @@
 ced 
-down 
 to a max
 imum
@@ -1387,16 +1387,18 @@
  max
-imum
  of 
+PEERS_
 MAX_
@@ -1518,16 +1518,22 @@
 eDelay: 
+PEERS_
 INITIAL_
@@ -1566,16 +1566,22 @@
 xDelay: 
+PEERS_
 MAX_REFE
@@ -1609,16 +1609,30 @@
 ackoff: 
+PEERS_REFETCH_
 BACKOFF_

reduce listPeers polling frequency