const { toast } = require('bulma-toast');
const cbor = require('borc');

const actions = require('./actions');

function errorToast(err) {
    console.error(err);
    return toast({
        message: err,
        type: 'is-warning',
        duration: 5000,
    });
}

// Create WebSocket connection.
// requires the redux store in order to push updates
// to components
function createSocket(store) {
    const ws = new WebSocket('ws://localhost:40000');
    ws.binaryType = 'arraybuffer';

    // handle account auth within the socket itself
    // https://www.christian-schneider.net/CrossSiteWebSocketHijacking.html
    let account = null;

    function send(msg) {
        msg.token = account && account.token;
        ws.send(cbor.encode(msg));
    }

    function accountLogin(res) {
        const [struct, login] = res;

        account = login;
        store.dispatch(actions.setAccount(login));
        console.log(account);
        return send({ method: 'cryp_spawn', params: { name: 'drake' }});
    }

    function crypSpawn(cryp) {
        console.log('got a new cryp', cryp);
    }

    const handlers = {
        cryp_spawn: crypSpawn,
        account_login: accountLogin,
        account_create: accountLogin,
    };

    function onMessage(event) {
        // decode binary msg from server
        const blob = new Uint8Array(event.data);
        const res = cbor.decode(blob);
        console.log(res);

        // check for error and split into response type and data
        if (res.err) return errorToast(res.err);
        const { method, params } = res;
        return handlers[method](params);
    }

    // Connection opened
    ws.addEventListener('open', function wsOpen(event) {
        // send({ method: 'account_create', params: { name: 'ntr', password: 'grepgrepgrep' }});
        send({ method: 'account_login', params: { name: 'ntr', password: 'grepgrepgrep' } });
    });

    // Listen for messages
    ws.addEventListener('message', onMessage);

    ws.addEventListener('error', function wsError(event) {
        console.error('WebSocket error', event);
        account = null;
    });

    ws.addEventListener('close', function wsClose(event) {
        console.error('WebSocket closed', event);
        account = null;
    });
}

module.exports = createSocket;
