import { Middleware } from 'redux'
import Transport from '@store-sync/transport'
import Differ from '@store-sync/differ'

type StoreSyncOptions = {
  transport: Transport
  differ: Differ<object>
}

const StoreSync: (options: StoreSyncOptions) => Middleware = ({
  transport,
  differ,
}) => store => {
  transport.addMessageListener(({ diff, datetime }) => {
    store.dispatch({
      type: 'STORE_SYNC_UPDATE',
      payload: diff,
      meta: {
        datetime,
      },
    })
  })
  return next => action => {
    const currentState = store.getState()
    const nextState = next(action)
    const diff = differ.diff(currentState, nextState)
    transport.send({ datetime: Date.now(), diff })
    return nextState
  }
}

export default StoreSync
