var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import React, { useState, useEffect, useCallback } from 'react';
import { WebView } from 'react-native-webview';
import webInterfaceHex from './web-interface';
import { hexToString, bytesToHexString } from './helpers';
import { validateSetProfile, validateSetup } from './validators';
import { View } from 'react-native';
const html = hexToString(webInterfaceHex);
const webCallPromises = {};
let msgIdNonce = 0;
let webReady = false;
const propCache = {};
const isNew = (method, params) => {
    const newProps = JSON.stringify(params);
    const cachedProps = propCache[method];
    return cachedProps !== newProps;
};
const setParams = (method, params) => {
    propCache[method] = JSON.stringify(params);
};
export default ({ onApiReady, seed, onKeyPair, onKeyPairError, setup, onSetup, onSetupError, url, onUrlParse, onUrlParseError, profile, onProfileSet, onProfileSetError }) => {
    const [webViewRef, setRef] = useState(null);
    const handleWebActionResponse = (event) => {
        const { msgId, result, error } = JSON.parse(event.nativeEvent.data);
        const cachedPromise = webCallPromises[msgId];
        if (cachedPromise) {
            if (error) {
                console.error(`Web response: ${error}`);
                cachedPromise.reject(new Error(error));
            }
            else {
                cachedPromise.resolve(result);
            }
            delete webCallPromises[msgId];
        }
        else {
            console.log(`Unknown msgId web result ${event.nativeEvent.data}`);
        }
    };
    const callWebAction = useCallback((method, validationCheck, prepParams, params, timeout = 3000) => __awaiter(void 0, void 0, void 0, function* () {
        if (!params || !isNew(method, params)) {
            return;
        }
        if (!webReady) {
            throw new Error('Slashtags API not ready');
        }
        console.log(`Validating ${method}...`);
        setParams(method, params);
        validationCheck(params);
        const formattedParams = prepParams(params);
        console.log(`Processing ${method}...`);
        msgIdNonce += 1;
        const javascript = `
		        webAction('${msgIdNonce}', '${method}', '${JSON.stringify(formattedParams)}'); void(0);
		      `;
        if (!webViewRef) {
            throw new Error('webViewRef not set');
        }
        webViewRef.injectJavaScript(javascript);
        return yield new Promise(function (resolve, reject) {
            webCallPromises[msgIdNonce] = { resolve, reject, time: new Date() };
            setTimeout(() => {
                if (webCallPromises[msgIdNonce]) {
                    const errMsg = `Interface method call '${method}' timeout`;
                    console.error(errMsg);
                    webCallPromises[msgIdNonce].reject(new Error(errMsg));
                }
            }, timeout);
        });
    }), [webViewRef]);
    const setServerStarted = () => {
        webReady = true;
        onApiReady === null || onApiReady === void 0 ? void 0 : onApiReady();
    };
    useEffect(() => {
        callWebAction('generateSeedKeyPair', () => { }, (params) => params, seed, 1000)
            .then((keyPair) => keyPair && onKeyPair({ seed: seed !== null && seed !== void 0 ? seed : '', keyPair }))
            .catch(onKeyPairError);
    }, [seed, onKeyPair, onKeyPairError, callWebAction]);
    useEffect(() => {
        const format = (params) => {
            if (typeof params.primaryKey !== 'string') {
                params.primaryKey = bytesToHexString(params.primaryKey);
            }
            return params;
        };
        callWebAction('setupSDK', validateSetup, format, setup, 1000)
            .then((res) => res && onSetup(res))
            .catch(onSetupError);
    }, [setup, onSetup, onSetupError, callWebAction]);
    useEffect(() => {
        callWebAction('parseUrl', () => { }, (params) => params, url, 1000)
            .then((parsed) => {
            parsed && onUrlParse(parsed);
        })
            .catch(onUrlParseError);
    }, [url, onUrlParse, onUrlParseError, callWebAction]);
    useEffect(() => {
        callWebAction('setProfile', validateSetProfile, (params) => params, profile, 1000)
            .then((res) => {
            res && onProfileSet(res);
        })
            .catch(onProfileSetError);
    }, [profile, onProfileSet, onProfileSetError, callWebAction]);
    return (<View style={{ width: 0, height: 0 }}>
			<WebView cacheMode={'LOAD_NO_CACHE'} ref={(r) => {
            setRef(r);
        }} source={{ html }} onLoad={setServerStarted} onMessage={handleWebActionResponse} onHttpError={console.error} onError={(e) => {
            console.warn('Web view error:');
            console.warn(console.error);
        }}/>
		</View>);
};
//# sourceMappingURL=index-callbacks.js.map