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, { forwardRef, useRef, useImperativeHandle, useState } 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 = {};
export default forwardRef(({ onApiReady }, ref) => {
    let webViewRef = useRef();
    const [msgIdNonce, setMsgIdNonce] = useState(0);
    const [webReady, setWebReady] = useState(false);
    const handleWebActionResponse = (event) => {
        const { msgId, result, error } = JSON.parse(event.nativeEvent.data);
        const cachedPromise = webCallPromises[msgId];
        if (cachedPromise) {
            if (error) {
                console.error(error);
                cachedPromise.reject(error);
            }
            else {
                cachedPromise.resolve(result);
            }
            delete webCallPromises[msgId];
        }
    };
    const callWebAction = (method, params, timeout = 3000) => __awaiter(void 0, void 0, void 0, function* () {
        if (!webReady) {
            throw new Error('Slashtags API not ready');
        }
        const javascript = `
		        webAction('${msgIdNonce}', '${method}', '${JSON.stringify(params)}'); void(0);
		      `;
        setMsgIdNonce(msgIdNonce + 1);
        if (!webViewRef) {
            throw 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(errMsg);
                }
            }, timeout);
        });
    });
    const setServerStarted = () => {
        setWebReady(true);
        onApiReady();
    };
    useImperativeHandle(ref, () => ({
        generateSeedKeyPair(seed) {
            return __awaiter(this, void 0, void 0, function* () {
                return yield callWebAction('generateSeedKeyPair', { seed }, 1000);
            });
        },
        setupSDK(params) {
            return __awaiter(this, void 0, void 0, function* () {
                validateSetup(params);
                if (typeof params.primaryKey !== 'string') {
                    params.primaryKey = bytesToHexString(params.primaryKey);
                }
                yield callWebAction('setupSDK', params, 1000);
            });
        },
        setProfile(params) {
            return __awaiter(this, void 0, void 0, function* () {
                validateSetProfile(params);
                return yield callWebAction('setProfile', params, 1000);
            });
        },
        parseUrl(url) {
            return __awaiter(this, void 0, void 0, function* () {
                return yield callWebAction('parseUrl', { url }, 500);
            });
        },
        slashUrl(url) {
            return __awaiter(this, void 0, void 0, function* () {
                return yield callWebAction('slashUrl', { url }, 10000);
            });
        },
        state(message) {
            return __awaiter(this, void 0, void 0, function* () {
                return yield callWebAction('state', { message }, 1000);
            });
        }
    }));
    return (<View style={{ width: 0, height: 0 }}>
			<WebView cacheMode={'LOAD_NO_CACHE'} ref={(r) => {
            webViewRef = r;
        }} source={{ html }} onLoad={setServerStarted} onMessage={handleWebActionResponse} onHttpError={console.error} onError={(e) => {
            console.warn('Web view error:');
            console.warn(console.error);
        }}/>
		</View>);
});
//# sourceMappingURL=index.js.map