import { HubConnectionBuilder, LogLevel, HubConnectionState } from '@microsoft/signalr'
import { NotificationLogTypes } from './remote-notification.action.types'
import { METADATA_END_POINTS } from '../../helpers/action-urls'

const notificationServerConnectionStart = () => ({
    type: NotificationLogTypes.NOTIFICATION_LOG_CONNECTION_START
})


const notificationServerConnectionSuccess = response => ({
    type: NotificationLogTypes.NOTIFICATION_LOG_CONNECTED,
    payload: response
})

const notificationReceived = response => ({
    type: NotificationLogTypes.NOTIFICATION_LOG_RECEIVED_MESSAGE,
    payload: response
})

const notificationServerConnectionFailure = err => ({
    type: NotificationLogTypes.NOTIFICATION_LOG_CONNECTION_FAILURE,
    payload: err
})


export const startReceivingNotificationsAsync = () => {
    return async (dispatch, getState) => {
        const { RECEIVE_MESSAGE_NAME } = METADATA_END_POINTS.notification

        const {remoteNotification} = getState()
        const { hubConnection } = remoteNotification
        getConnectionInfo(hubConnection)
        hubConnection.on(RECEIVE_MESSAGE_NAME, message => {
            // console.log('received from server: ',message)    
            dispatch(notificationReceived(message))    
        })

    }
}


export const makeConnectionToHubAsync = (userId) => {
    return async (dispatch, getState) => {
        dispatch(notificationServerConnectionStart())
        try{
            const { METTA_HUB_CONNECTION } = METADATA_END_POINTS.notification
            const newConnection = new HubConnectionBuilder()
                .withUrl(`${METTA_HUB_CONNECTION}?userId=${userId}`)
                .configureLogging(LogLevel.Information)
                // .withUrl('/api/chatHub')
                .withAutomaticReconnect()
                .build()
                if (newConnection) {
                    await newConnection.start()
                    dispatch(notificationServerConnectionSuccess(newConnection))
                    
                    newConnection.onclose( () => {
                        console.log('reconnecting in 5 secs ...')
                        dispatch(notificationServerConnectionFailure({message: `closed connection`}))
                    })

                    newConnection.onreconnected(connectionId => {
                        dispatch(notificationServerConnectionStart())
                        console.assert(newConnection.state === HubConnectionState.Connected)
                        
                        console.log( `Connection reestablished. Connected with connectionId "${connectionId}".`)
                        dispatch(notificationServerConnectionSuccess(newConnection))
                        
                    })
                }
    
            
        }catch(ex){            
            console.log("Error is: ", ex)
            dispatch(notificationServerConnectionFailure({message: `error establishing connection due to ${ex}`}))

        }
    }
}

const getConnectionInfo = async (connection) => {
    if (connection.connectionStarted) {
        try {
            const connectionId = await  connection.invoke('GetConnectionId');
            // await  connection.invoke('PushNotification', user, message);
            // await  connection.send('SendMessage', chatMessage)
            console.log('connection Id = ',connectionId)
        }
        catch(e) {
            console.log(e)
        }
    }
    else {
        console.log('No connection to server yet.')
    }
}

